/**
   * Set the default locator if this field is mandatory and we have a warehouse restriction.
   *
   * @since 3.1.4
   */
  private void setDefault_Locator_ID() {
    // teo_sarca, FR [ 1661546 ] Mandatory locator fields should use defaults

    if (!isMandatory() || m_mLocator == null) {
      return;
    }

    int M_Warehouse_ID = getOnly_Warehouse_ID();

    if (M_Warehouse_ID <= 0) {
      return;
    }

    MWarehouse wh = MWarehouse.get(Env.getCtx(), M_Warehouse_ID);

    if (wh == null || wh.get_ID() <= 0) {
      return;
    }

    MLocator loc = wh.getDefaultLocator();

    if (loc == null || loc.get_ID() <= 0) {
      return;
    }

    setValue(Integer.valueOf(loc.get_ID()));
  }
Beispiel #2
0
  /**
   * Perrform process.
   *
   * @return Message
   * @throws Exception if not successful
   */
  protected String doIt() throws Exception {
    log.info(
        "M_Warehouse_ID="
            + p_M_Warehouse_ID
            + ", C_BPartner_ID="
            + p_C_BPartner_ID
            + " - ReplenishmentCreate="
            + p_ReplenishmentCreate
            + ", C_DocType_ID="
            + p_C_DocType_ID);
    if (p_ReplenishmentCreate != null && p_C_DocType_ID == 0)
      throw new AdempiereUserError("@FillMandatory@ @C_DocType_ID@");

    MWarehouse wh = MWarehouse.get(getCtx(), p_M_Warehouse_ID);
    if (wh.get_ID() == 0) throw new AdempiereSystemError("@FillMandatory@ @M_Warehouse_ID@");
    //
    prepareTable();
    fillTable(wh);
    //
    if (p_ReplenishmentCreate == null) return "OK";
    //
    MDocType dt = MDocType.get(getCtx(), p_C_DocType_ID);
    if (!dt.getDocBaseType().equals(p_ReplenishmentCreate))
      throw new AdempiereSystemError(
          "@C_DocType_ID@=" + dt.getName() + " <> " + p_ReplenishmentCreate);
    //
    if (p_ReplenishmentCreate.equals("POO")) createPO();
    else if (p_ReplenishmentCreate.equals("POR")) createRequisition();
    else if (p_ReplenishmentCreate.equals("MMM")) createMovements();
    return m_info;
  } //	doIt
  /** 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;
  }
 @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();
 }
  /** execute the Valuation Effective Date */
  protected String doIt() throws Exception {
    setup();

    for (MWarehouse warehouse : warehouses)
      for (MCostType costType : costTypes)
        for (MCostElement costElement : costElements)
          generateInventoryValue(
              warehouse.getM_Warehouse_ID(),
              costType.getM_CostType_ID(),
              costElement.getM_CostElement_ID());

    DB.executeUpdate(
        "UPDATE T_InventoryValue SET cost = CASE WHEN QtyOnHand <> 0 THEN (CostAmt + CostAmtLL) / QtyOnHand ELSE  0 END  , CumulatedAmt = CostAmt + CostAmtLL,  DateValue = "
            + DB.TO_DATE(p_DateValue)
            + " WHERE AD_PInstance_ID=?",
        getAD_PInstance_ID(),
        get_TrxName());

    return "@Ok@";
  }
Beispiel #6
0
  /** Create PO's */
  private void createPO() {
    int noOrders = 0;
    String info = "";
    //
    MOrder order = null;
    MWarehouse wh = null;
    X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL");
    for (int i = 0; i < replenishs.length; i++) {
      X_T_Replenish replenish = replenishs[i];
      if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
        wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
      //
      if (order == null
          || order.getC_BPartner_ID() != replenish.getC_BPartner_ID()
          || order.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) {
        order = new MOrder(getCtx(), 0, get_TrxName());
        order.setIsSOTrx(false);
        order.setC_DocTypeTarget_ID(p_C_DocType_ID);

        final MBPartner bp = new MBPartner(getCtx(), replenish.getC_BPartner_ID(), get_TrxName());
        Services.get(IOrderBL.class).setBPartner(order, bp);

        order.setSalesRep_ID(getAD_User_ID());
        order.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
        //	Set Org/WH
        order.setAD_Org_ID(wh.getAD_Org_ID());
        order.setM_Warehouse_ID(wh.getM_Warehouse_ID());
        if (!order.save()) return;
        log.debug(order.toString());
        noOrders++;
        info += " - " + order.getDocumentNo();
      }
      MOrderLine line = new MOrderLine(order);
      line.setM_Product_ID(replenish.getM_Product_ID());
      line.setQty(replenish.getQtyToOrder());
      line.setPrice();
      line.save();
    }
    m_info = "#" + noOrders + info;
    log.info(m_info);
  } //	createPO
  /** Setup the collections */
  private void setup() {
    if (p_M_CostType_ID > 0) costTypes.add(new MCostType(getCtx(), p_M_CostType_ID, get_TrxName()));
    else costTypes = MCostType.get(getCtx(), get_TrxName());

    if (p_M_CostElement_ID > 0) costElements.add(MCostElement.get(getCtx(), p_M_CostElement_ID));
    else costElements = MCostElement.getCostElement(getCtx(), get_TrxName());

    if (p_M_Warehouse_ID > 0)
      warehouses.add(MWarehouse.get(getCtx(), p_M_Warehouse_ID, get_TrxName()));
    else {
      warehouses =
          new Query(getCtx(), MWarehouse.Table_Name, "", get_TrxName()).setClient_ID().list();
    }
  }
Beispiel #8
0
 /** Create Requisition */
 private void createRequisition() {
   int noReqs = 0;
   String info = "";
   //
   MRequisition requisition = null;
   MWarehouse wh = null;
   X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL");
   for (int i = 0; i < replenishs.length; i++) {
     X_T_Replenish replenish = replenishs[i];
     if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
       wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
     //
     if (requisition == null || requisition.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) {
       requisition = new MRequisition(getCtx(), 0, get_TrxName());
       requisition.setAD_User_ID(getAD_User_ID());
       requisition.setC_DocType_ID(p_C_DocType_ID);
       requisition.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
       //	Set Org/WH
       requisition.setAD_Org_ID(wh.getAD_Org_ID());
       requisition.setM_Warehouse_ID(wh.getM_Warehouse_ID());
       if (!requisition.save()) return;
       log.debug(requisition.toString());
       noReqs++;
       info += " - " + requisition.getDocumentNo();
     }
     //
     MRequisitionLine line = new MRequisitionLine(requisition);
     line.setM_Product_ID(replenish.getM_Product_ID());
     line.setC_BPartner_ID(replenish.getC_BPartner_ID());
     line.setQty(replenish.getQtyToOrder());
     line.setPrice();
     line.save();
   }
   m_info = "#" + noReqs + info;
   log.info(m_info);
 } //	createRequisition
Beispiel #9
0
  /** Create Inventory Movements */
  private void createMovements() {
    int noMoves = 0;
    String info = "";
    //
    MClient client = null;
    MMovement move = null;
    int M_Warehouse_ID = 0;
    int M_WarehouseSource_ID = 0;
    MWarehouse whSource = null;
    MWarehouse wh = null;
    X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NOT NULL");
    for (int i = 0; i < replenishs.length; i++) {
      X_T_Replenish replenish = replenishs[i];
      if (whSource == null
          || whSource.getM_WarehouseSource_ID() != replenish.getM_WarehouseSource_ID())
        whSource = MWarehouse.get(getCtx(), replenish.getM_WarehouseSource_ID());
      if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
        wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
      if (client == null || client.getAD_Client_ID() != whSource.getAD_Client_ID())
        client = MClient.get(getCtx(), whSource.getAD_Client_ID());
      //
      if (move == null
          || M_WarehouseSource_ID != replenish.getM_WarehouseSource_ID()
          || M_Warehouse_ID != replenish.getM_Warehouse_ID()) {
        M_WarehouseSource_ID = replenish.getM_WarehouseSource_ID();
        M_Warehouse_ID = replenish.getM_Warehouse_ID();

        move = new MMovement(getCtx(), 0, get_TrxName());
        move.setC_DocType_ID(p_C_DocType_ID);
        move.setDescription(
            Msg.getMsg(getCtx(), "Replenishment")
                + ": "
                + whSource.getName()
                + "->"
                + wh.getName());
        //	Set Org
        move.setAD_Org_ID(whSource.getAD_Org_ID());
        if (!move.save()) return;
        log.debug(move.toString());
        noMoves++;
        info += " - " + move.getDocumentNo();
      }
      //	To
      int M_LocatorTo_ID = wh.getDefaultLocator().getM_Locator_ID();
      //	From: Look-up Storage
      MProduct product = MProduct.get(getCtx(), replenish.getM_Product_ID());
      String MMPolicy = product.getMMPolicy();
      MStorage[] storages =
          MStorage.getWarehouse(
              getCtx(),
              whSource.getM_Warehouse_ID(),
              replenish.getM_Product_ID(),
              0,
              0,
              true,
              null,
              MClient.MMPOLICY_FiFo.equals(MMPolicy),
              get_TrxName());
      //
      BigDecimal target = replenish.getQtyToOrder();
      for (int j = 0; j < storages.length; j++) {
        MStorage storage = storages[j];
        if (storage.getQtyOnHand().signum() <= 0) continue;
        BigDecimal moveQty = target;
        if (storage.getQtyOnHand().compareTo(moveQty) < 0) moveQty = storage.getQtyOnHand();
        //
        MMovementLine line = new MMovementLine(move);
        line.setM_Product_ID(replenish.getM_Product_ID());
        line.setMovementQty(moveQty);
        if (replenish.getQtyToOrder().compareTo(moveQty) != 0)
          line.setDescription("Total: " + replenish.getQtyToOrder());
        line.setM_Locator_ID(storage.getM_Locator_ID()); // 	from
        line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
        line.setM_LocatorTo_ID(M_LocatorTo_ID); // 	to
        line.setM_AttributeSetInstanceTo_ID(storage.getM_AttributeSetInstance_ID());
        line.save();
        //
        target = target.subtract(moveQty);
        if (target.signum() == 0) break;
      }
    }
    if (replenishs.length == 0) {
      m_info = "No Source Warehouse";
      log.warn(m_info);
    } else {
      m_info = "#" + noMoves + info;
      log.info(m_info);
    }
  } //	createRequisition
Beispiel #10
0
  /**
   * Fill Table
   *
   * @param wh warehouse
   */
  private void fillTable(MWarehouse wh) throws Exception {
    String sql =
        "INSERT INTO T_Replenish "
            + "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID,"
            + " ReplenishType, Level_Min, Level_Max,"
            + " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate,"
            + " C_Calendar_ID, C_Period_ID, TimeToMarket)"
            + "SELECT "
            + getAD_PInstance_ID()
            + ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID,"
            + " r.ReplenishType, r.Level_Min, r.Level_Max,"
            + " po.C_BPartner_ID, po.Order_Min, po.Order_Pack, 0, ";
    if (p_ReplenishmentCreate == null) sql += "null";
    else sql += "'" + p_ReplenishmentCreate + "'";

    sql += ", r.C_Calendar_ID, r.C_Period_ID, r.TimeToMarket";

    sql +=
        " FROM M_Replenish r"
            + " INNER JOIN M_Product_PO po ON (r.M_Product_ID=po.M_Product_ID) "
            + "WHERE po.IsCurrentVendor='Y'" //	Only Current Vendor
            + " AND r.ReplenishType<>'0'"
            + " AND po.IsActive='Y' AND r.IsActive='Y'"
            + " AND r.M_Warehouse_ID="
            + p_M_Warehouse_ID;
    if (p_C_BPartner_ID != 0) sql += " AND po.C_BPartner_ID=" + p_C_BPartner_ID;
    int no = DB.executeUpdate(sql, get_TrxName());
    log.trace(sql);
    log.debug("Insert (1) #" + no);

    if (p_C_BPartner_ID == 0) {
      sql =
          "INSERT INTO T_Replenish "
              + "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID,"
              + " ReplenishType, Level_Min, Level_Max,"
              + " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate,"
              + " C_Calendar_ID, C_Period_ID, TimeToMarket)"
              + "SELECT "
              + getAD_PInstance_ID()
              + ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID,"
              + " r.ReplenishType, r.Level_Min, r.Level_Max,"
              + " 0, 1, 1, 0, ";
      if (p_ReplenishmentCreate == null) sql += "null";
      else sql += "'" + p_ReplenishmentCreate + "'";

      sql += ", r.C_Calendar_ID, r.C_Period_ID, r.TimeToMarket";

      sql +=
          " FROM M_Replenish r "
              + "WHERE r.ReplenishType<>'0' AND r.IsActive='Y'"
              + " AND r.M_Warehouse_ID="
              + p_M_Warehouse_ID
              + " AND NOT EXISTS (SELECT * FROM T_Replenish t "
              + "WHERE r.M_Product_ID=t.M_Product_ID"
              + " AND AD_PInstance_ID="
              + getAD_PInstance_ID()
              + ")";
      no = DB.executeUpdate(sql, get_TrxName());
      log.debug("Insert (BP) #" + no);
    }

    sql =
        "UPDATE T_Replenish t SET "
            + "QtyOnHand = (SELECT COALESCE(SUM(QtyOnHand),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
            + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID),"
            + "QtyReserved = (SELECT COALESCE(SUM(QtyReserved),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
            + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID),"
            + "QtyOrdered = (SELECT COALESCE(SUM(QtyOrdered),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
            + " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID)";
    if (p_C_DocType_ID != 0) sql += ", C_DocType_ID=" + p_C_DocType_ID;
    sql += " WHERE AD_PInstance_ID=" + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Update #" + no);

    //	Delete inactive products and replenishments
    sql =
        "DELETE FROM T_Replenish r "
            + "WHERE (EXISTS (SELECT * FROM M_Product p "
            + "WHERE p.M_Product_ID=r.M_Product_ID AND p.IsActive='N')"
            + " OR EXISTS (SELECT * FROM M_Replenish rr "
            + " WHERE rr.M_Product_ID=r.M_Product_ID AND rr.IsActive='N'))"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Deleted Inactive=" + no);

    //	Ensure Data consistency
    sql = "UPDATE T_Replenish SET QtyOnHand = 0 WHERE QtyOnHand IS NULL";
    no = DB.executeUpdate(sql, get_TrxName());
    sql = "UPDATE T_Replenish SET QtyReserved = 0 WHERE QtyReserved IS NULL";
    no = DB.executeUpdate(sql, get_TrxName());
    sql = "UPDATE T_Replenish SET QtyOrdered = 0 WHERE QtyOrdered IS NULL";
    no = DB.executeUpdate(sql, get_TrxName());

    //	Set Minimum / Maximum Maintain Level
    //	X_M_Replenish.REPLENISHTYPE_ReorderBelowMinimumLevel
    sql =
        "UPDATE T_Replenish"
            + " SET QtyToOrder = CASE WHEN QtyOnHand - QtyReserved + QtyOrdered <= Level_Min "
            + " THEN Level_Max - QtyOnHand + QtyReserved - QtyOrdered "
            + " ELSE 0 END "
            + "WHERE ReplenishType='1'"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Update Type-1=" + no);
    //
    //	X_M_Replenish.REPLENISHTYPE_MaintainMaximumLevel
    sql =
        "UPDATE T_Replenish"
            + " SET QtyToOrder = Level_Max - QtyOnHand + QtyReserved - QtyOrdered "
            + "WHERE ReplenishType='2'"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Update Type-2=" + no);

    //	Minimum Order Quantity
    sql =
        "UPDATE T_Replenish"
            + " SET QtyToOrder = Order_Min "
            + "WHERE QtyToOrder < Order_Min"
            + " AND QtyToOrder > 0"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Set MinOrderQty=" + no);

    //	Even dividable by Pack
    sql =
        "UPDATE T_Replenish"
            + " SET QtyToOrder = QtyToOrder - MOD(QtyToOrder, Order_Pack) + Order_Pack "
            + "WHERE MOD(QtyToOrder, Order_Pack) <> 0"
            + " AND QtyToOrder > 0"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Set OrderPackQty=" + no);

    //	Source from other warehouse
    if (wh.getM_WarehouseSource_ID() != 0) {
      sql =
          "UPDATE T_Replenish"
              + " SET M_WarehouseSource_ID="
              + wh.getM_WarehouseSource_ID()
              + " WHERE AD_PInstance_ID="
              + getAD_PInstance_ID();
      no = DB.executeUpdate(sql, get_TrxName());
      if (no != 0) log.debug("Set Source Warehouse=" + no);
    }
    //	Check Source Warehouse
    sql =
        "UPDATE T_Replenish"
            + " SET M_WarehouseSource_ID = NULL "
            + "WHERE M_Warehouse_ID=M_WarehouseSource_ID"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Set same Source Warehouse=" + no);

    //	Custom Replenishment
    String className = wh.getReplenishmentClass();
    if (className != null && className.length() > 0) {
      //	Get Replenishment Class
      ReplenishInterface custom = null;
      try {
        Class<?> clazz = Class.forName(className);
        custom = (ReplenishInterface) clazz.newInstance();
      } catch (Exception e) {
        throw new AdempiereUserError(
            "No custom Replenishment class " + className + " - " + e.toString());
      }
      excecReplenishInterface(wh, custom, X_M_Replenish.REPLENISHTYPE_Custom);
    }

    // metas
    // X_M_Replenish.REPLENISHTYPE_EnsureFutureCapacity
    final ReplenishInterface replenishForFutureCapacity = new ReplenishForFutureQtyServiceInvoker();
    excecReplenishInterface(
        wh, replenishForFutureCapacity, Constants.REPLENISHTYPE_EnsureFutureQty);
    // metas end

    //	Delete rows where nothing to order
    sql =
        "DELETE FROM T_Replenish "
            + "WHERE QtyToOrder < 1"
            + " AND AD_PInstance_ID="
            + getAD_PInstance_ID();
    no = DB.executeUpdate(sql, get_TrxName());
    if (no != 0) log.debug("Deleted No QtyToOrder=" + no);
  } //	fillTable
  public String readFile() throws IOException {

    File inputWorkbook = new File(archivo);
    Workbook w;
    try {
      String msg = "";
      w = Workbook.getWorkbook(inputWorkbook);
      // Get the first sheet
      Sheet sheet = w.getSheet(0);

      // int defaultRows = sheet.getRows();

      // Si la cantidad de columnas es 4
      if (sheet.getColumns() >= 4 && sheet.getRows() > 1) {

        // Valido que las cabeceras tengan el formato correcto
        if (!sheet.getCell(0, 0).getContents().equals("ORIGEN")
            || !sheet.getCell(1, 0).getContents().equals("DESTINO")
            || !sheet.getCell(2, 0).getContents().equals("PRODUCTO")
            || !sheet.getCell(3, 0).getContents().equals("PIEZAS")) {
          msg = Msg.translate(getCtx(), "Column Names");
          return msg;
        }

        // El vector que almacena la estructura de traspasos
        Vector<Movimiento> movimientos = new Vector<Movimiento>();
        Iterator<Movimiento> iterator_movimientos = null;
        Movimiento movimiento_temporal = null, movimiento_nuevo = null;
        for (int i = 1;
            i < sheet.getRows() && getStore(sheet.getCell(0, i).getContents()) != null;
            i++) {

          // Capturo el origen
          MWarehouse origen = getStore(sheet.getCell(0, i).getContents());
          MWarehouse destino = getStore(sheet.getCell(1, i).getContents());

          String isStore = "N";
          // Aca debo bucar los values de los m_warehouse que son cd
          String sql =
              "SELECT XX_IsStore FROM M_Warehouse WHERE M_Warehouse_ID in ( "
                  + origen.getM_Warehouse_ID()
                  + ","
                  + destino.getM_Warehouse_ID()
                  + ")";
          PreparedStatement pstmt = null;
          ResultSet rs = null;
          try {
            pstmt = DB.prepareStatement(sql, null);
            rs = pstmt.executeQuery();

            while (rs.next()) {
              if (rs.getString(1).equals("Y")) isStore = rs.getString(1);
            }

          } catch (Exception a) {
            log.log(Level.SEVERE, sql, a);
          } finally {
            DB.closeResultSet(rs);
            DB.closeStatement(pstmt);
          }

          if (origen == null || isStore.equals("Y"))
            return Msg.translate(getCtx(), "Cell A Error")
                + (i + 1)
                + " "
                + sheet.getCell(0, i).getContents();

          // Capturo el destino

          if (destino == null || isStore.equals("Y"))
            return Msg.translate(getCtx(), "Cell B Error")
                + (i + 1)
                + " "
                + sheet.getCell(1, i).getContents();

          // Capturo el producto
          String p_id = sheet.getCell(2, i).getContents();
          MProduct producto = getProduct(p_id);
          if (producto == null) {
            return Msg.translate(getCtx(), "Cell C Error")
                + (i + 1)
                + " "
                + sheet.getCell(2, i).getContents();
          }

          // Capturo las piezas
          Double piezas = null;
          try {
            if (sheet.getCell(3, i) != null)
              piezas = Double.parseDouble(sheet.getCell(3, i).getContents());
          } catch (NumberFormatException e) {
            return Msg.translate(getCtx(), "Cell D Error")
                + (i + 1)
                + " "
                + sheet.getCell(3, i).getContents();
          }
          if (piezas == null) {
            return Msg.translate(getCtx(), "Cell D Error")
                + (i + 1)
                + " "
                + sheet.getCell(3, i).getContents();
          }

          // Agregar cada fila al vector de traspasos
          iterator_movimientos = movimientos.iterator();
          boolean encontrado = false;
          while (iterator_movimientos.hasNext()) {
            movimiento_temporal = iterator_movimientos.next();

            // Si un traspaso anterior va a la misma tienda, departamento, etc
            if (movimiento_temporal.origen == origen.get_ID()) {
              if (movimiento_temporal.destino == destino.get_ID()) {
                if (movimiento_temporal.departamento == producto.getXX_VMR_Department_ID()) {
                  // Entonces agregar algo al objeto traspaso

                  movimiento_temporal.agregarCantidades(producto.get_ID(), piezas);
                  encontrado = true;
                  break;
                }
              }
            }
          }

          // Si no se encontró en el vector de traspasos agregarlo
          if (!encontrado) {
            movimiento_nuevo =
                new Movimiento(
                    origen.get_ID(), destino.get_ID(), producto.getXX_VMR_Department_ID());
            movimiento_nuevo.agregarCantidades(producto.get_ID(), piezas);
            movimientos.add(movimiento_nuevo);
          }
        }

        // Una vez leido todo el archivo se procede a crear los traspasos
        // System.out.println(traspasos);
        return procesarMovimientos(movimientos).toString();

      } else {
        return Msg.translate(getCtx(), "4 Columns");
      }
    } catch (BiffException e) {
      log.log(Level.SEVERE, e.getMessage());
    }
    return "";
  }
  /** 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;
    }
  }
  /** Procesa los traspasos de el archivo excel */
  public StringBuffer procesarMovimientos(Vector<Movimiento> traspasos) {

    // Iterar sobre cada uno de los traspasos
    Iterator<Movimiento> itr = traspasos.iterator();
    Movimiento mov = null;

    MMovement movimiento = null;
    MMovementLine linea = null;
    StringBuffer buffer = new StringBuffer();

    String nl = " ----- ";

    // Consulta que me dice cuanto me queda en inventario de ese producto
    String sql =
        " WITH  DISPONIBLE AS ( select m_product_id, available from (SELECT M_PRODUCT_ID, sum(available) as available FROM  (SELECT M_PRODUCT_ID, SUM(QTY) AS AVAILABLE FROM M_STORAGEDETAIL  "
            + " WHERE M_LOCATOR_ID =? AND QTYTYPE = 'H'  AND M_AttributeSetInstance_ID>=0  AND M_lOCATOR_ID >= 0  GROUP BY M_PRODUCT_ID HAVING SUM(QTY) > 0  union all  SELECT M_PRODUCT_ID, "
            + " -1*SUM(CANT) AS NOTAVAILABLE FROM  (SELECT M_PRODUCT_ID,SUM(XX_DESIREDQUANTITY) AS CANT FROM XX_VMR_DISTRIBDETAILTEMP where m_warehouse_id=? GROUP BY M_PRODUCT_ID  union all  SELECT M_PRODUCT_ID, SUM(XX_DISTRIBUTEDQTY) AS CANT "
            + " from XX_VMR_PO_PRODUCTDISTRIB D JOIN XX_VMR_ORDER P ON (P.XX_VMR_DISTRIBUTIONHEADER_ID = D.XX_VMR_DISTRIBUTIONHEADER_ID) WHERE P.XX_ORDERREQUESTSTATUS = 'PE' GROUP BY M_PRODUCT_ID  union all  SELECT M_PRODUCT_ID,"
            + " SUM(XX_DISTRIBUTEDQTY) AS CANT from XX_VMR_PO_PRODUCTDISTRIB D JOIN XX_VMR_DistributionHeader H ON (h.XX_VMR_DISTRIBUTIONHEADER_ID = D.XX_VMR_DISTRIBUTIONHEADER_ID) WHERE H.XX_DistributionStatus IN ('QR', 'QT') GROUP BY M_PRODUCT_ID  )"
            + " GROUP BY M_PRODUCT_ID  ) GROUP BY M_PRODUCT_ID) where available>0) SELECT sum(IV.available) FROM  DISPONIBLE iv "
            + " JOIN M_PRODUCT p ON ( IV.M_PRODUCT_ID = p.M_PRODUCT_ID) JOIN XX_VMR_VENDORPRODREF vr ON ( vr.XX_VMR_VENDORPRODREF_ID = p.XX_VMR_VENDORPRODREF_ID)  LEFT OUTER JOIN M_ATTRIBUTESETINSTANCE att ON (p.M_ATTRIBUTESETINSTANCE_ID = att.M_ATTRIBUTESETINSTANCE_ID ) "
            + " WHERE    IV.M_PRODUCT_ID = ? GROUP BY iv.M_PRODUCT_ID, p.VALUE||'-'||p.NAME, iv.M_PRODUCT_ID, att.description, p.M_ATTRIBUTESETINSTANCE_ID HAVING SUM(IV.available)>0  ORDER BY iv.M_PRODUCT_ID";
    // System.out.println(sql);
    PreparedStatement ps = DB.prepareStatement(sql, null);
    ResultSet rs = null;

    while (itr.hasNext()) {
      mov = itr.next();
      movimiento = new MMovement(Env.getCtx(), 0, get_TrxName());

      // Se deben llenar los campos necesarios
      movimiento.setC_DocType_ID(1000335); // Movimiento entre CDs
      String mss = Msg.getMsg(Env.getCtx(), "XX_ImportedMovement", new String[] {archivo});
      movimiento.setDescription(mss);
      movimiento.setMovementDate(new Timestamp(Calendar.getInstance().getTimeInMillis()));

      // Si el origen es centro de distribucion, entonces es el locator chequeado
      MLocator desde = Utilities.obtenerLocatorEnTienda(mov.origen);
      movimiento.setM_Locator_ID(desde.get_ID());

      // El locator hasta, que es el locator chequeado del almacen destino
      MLocator hasta = Utilities.obtenerLocatorEnTransito(mov.destino);
      movimiento.setM_LocatorTo_ID(hasta.get_ID());

      // El resto de los campos
      movimiento.setXX_VMR_Department_ID(mov.departamento);
      /**
       * movimiento.setXX_TransferMotive_ID(
       * Env.getCtx().getContextAsInt("#XX_L_AUTOMATICTRANSFER_ID"));
       */
      movimiento.setM_WarehouseFrom_ID(mov.origen);
      movimiento.setM_WarehouseTo_ID(mov.destino);
      MWarehouse origen = new MWarehouse(getCtx(), mov.origen, null);
      movimiento.setAD_Org_ID(origen.getAD_Org_ID());

      try {
        if (!movimiento.save()) continue;
        commit();
        movimiento.load(get_TrxName());

        // Se copian cada una de las lineas al movimiento
        MProduct producto = null;
        BigDecimal precioVenta = null, costoCompra = null;
        Integer consecutivo = null;
        BigDecimal cantidadMovimiento = null,
            cantidadDisponible = null,
            cantidadDisponibleTotal = null;

        int created_lines = 0;
        for (int i = 0; i < mov.productos.size(); i++) {

          producto = new MProduct(Env.getCtx(), mov.productos.get(i), get_TrxName());
          System.out.println("Producto: " + producto.getValue());
          // Calcular los consecutivos en funcion del inventario
          try {
            ps.setInt(1, Utilities.obtenerLocatorEnTienda(mov.origen).getM_Locator_ID());
            ps.setInt(2, mov.origen);
            ps.setInt(3, producto.get_ID());
            cantidadMovimiento = mov.cantidades.get(i);
            cantidadDisponibleTotal = Env.ZERO;

            rs = ps.executeQuery();

            // Debo buscar las cantidades que tengo en el almacen origen de ese producto

            int cantidadInventario = 0;

            if (rs.next()) {

              cantidadInventario = rs.getInt(1);

              // Crear la linea - si la cantidad disponible es positiva
              if (cantidadInventario > 0) {

                if (cantidadMovimiento.intValue() > cantidadInventario)
                  cantidadMovimiento = new BigDecimal(cantidadInventario);

                // Si la cantidad total en inventario es positiva, ahora buscamos la cantidad que
                // hay por lote
                String sql3 =
                    " SELECT STO.M_ATTRIBUTESETINSTANCE_ID, STO.QTY AS QTYONHAND "
                        + " FROM M_STORAGEDETAIL STO WHERE STO.M_PRODUCT_ID = "
                        + producto.get_ID()
                        + " AND STO.M_LOCATOR_ID = "
                        + Utilities.obtenerLocatorEnTienda(mov.origen).getM_Locator_ID()
                        + " AND STO.QTYTYPE = '"
                        + X_Ref_Quantity_Type.ON_HAND.getValue()
                        + "' "
                        + " AND STO.QTY > 0 "
                        + " AND STO.M_AttributeSetInstance_ID>=0"
                        + " AND STO.M_lOCATOR_ID >= 0"
                        + " ORDER BY STO.M_ATTRIBUTESETINSTANCE_ID ASC";
                PreparedStatement ps3 = DB.prepareStatement(sql3, null);
                ResultSet rs3 = ps3.executeQuery();
                while (rs3.next() && cantidadMovimiento.intValue() > 0) {
                  linea = new MMovementLine(Env.getCtx(), 0, get_TrxName());
                  linea.setM_LocatorTo_ID(movimiento.getM_LocatorTo_ID());
                  linea.setM_Locator_ID(movimiento.getM_Locator_ID());
                  linea.setM_Movement_ID(movimiento.get_ID());
                  linea.setM_Product_ID(producto.get_ID());
                  linea.setM_AttributeSetInstance_ID(rs3.getInt(1));
                  linea.setAD_Org_ID(origen.getAD_Org_ID());
                  linea.setXX_SalePrice(new BigDecimal(0.01));

                  if (producto.getXX_VMR_Brand_ID() != 0)
                    linea.setXX_VMR_Brand_ID(producto.getXX_VMR_Brand_ID());
                  if (producto.getXX_VMR_Line_ID() != 0)
                    linea.setXX_VMR_Line_ID(producto.getXX_VMR_Line_ID());
                  if (producto.getXX_VMR_Section_ID() != 0)
                    linea.setXX_VMR_Section_ID(producto.getXX_VMR_Section_ID());

                  if (producto.getC_TaxCategory_ID() != 0) {
                    linea.setC_TaxCategory_ID(producto.getC_TaxCategory_ID());

                    // Si es mayor que la cantidad solicitada
                    if (rs3.getInt(2) > cantidadMovimiento.intValue()) {

                      linea.setQtyRequired(cantidadMovimiento);
                      linea.setMovementQty(cantidadMovimiento);
                      cantidadMovimiento = Env.ZERO;

                    } else {

                      linea.setQtyRequired(new BigDecimal(rs3.getInt(2)));
                      linea.setMovementQty(new BigDecimal(rs3.getInt(2)));
                      cantidadMovimiento =
                          cantidadMovimiento.subtract(new BigDecimal(rs3.getInt(2)));
                    }
                    // En este caso se almacena
                    if (linea.save()) created_lines++;
                  }
                }
                DB.closeStatement(ps3);
                DB.closeResultSet(rs3);
              }
            }

            // No fueron suficientes piezas
            if (cantidadMovimiento.compareTo(Env.ZERO) == 1) {

              if (mov.cantidades.get(i).compareTo(new BigDecimal(cantidadInventario)) == 1) {

                buffer.append(producto.getValue());
                buffer.append(" " + producto.getName() + " ");
                String msg =
                    Msg.getMsg(
                        Env.getCtx(),
                        "XX_ReqLessThanAvail",
                        new String[] {
                          "" + mov.cantidades.get(i),
                          "" + cantidadInventario,
                          Msg.translate(getCtx(), "All")
                        });
                buffer.append(msg);
                buffer.append(nl);
              }
            }

          } catch (SQLException e) {
            buffer.append(Msg.translate(Env.getCtx(), "XX_ProductPConsecNotFound"));
            buffer.append(" : ");
            buffer.append(producto.getValue() + "-" + producto.getName());
            buffer.append(" - ");
            buffer.append(nl);
          } finally {

          }
        }
        // System.out.println("MOVIMIENTO: "+movimiento.getM_Movement_ID());
        // Si no se creo ninguna linea
        if (created_lines == 0) {
          movimiento.delete(true, get_TrxName());
          buffer.append(Msg.translate(Env.getCtx(), "XX_MovementIgnored") + " ");
          buffer.append(mov.toString());
          buffer.append(nl);
          // AGREGADO POR GHUCHET
        } else {
          //					completarMovimiento(movimiento);
        }
        // HASTA AQUI AGREGADO POR GHUCHET
      } catch (Exception e) {
        log.log(Level.SEVERE, Msg.translate(Env.getCtx(), "XX_DatabaseAccessError"), e);
        buffer.append(Msg.translate(Env.getCtx(), "XX_DatabaseAccessError"));
        buffer.append(nl);
      }
    }
    return buffer;
  }
  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();
    }
  }