/** Business logic to execute. */
  public VOListResponse updateCharges(
      ArrayList oldVOs,
      ArrayList newVOs,
      String serverLanguageId,
      String username,
      ArrayList customizedFields)
      throws Throwable {
    Connection conn = null;
    try {
      if (this.conn == null) conn = getConn();
      else conn = this.conn;

      ChargeVO oldVO = null;
      ChargeVO newVO = null;
      Response res = null;

      for (int i = 0; i < oldVOs.size(); i++) {
        oldVO = (ChargeVO) oldVOs.get(i);
        newVO = (ChargeVO) newVOs.get(i);

        // update SYS10 table...
        TranslationUtils.updateTranslation(
            oldVO.getDescriptionSYS10(),
            newVO.getDescriptionSYS10(),
            newVO.getProgressiveSys10SAL06(),
            serverLanguageId,
            conn);

        HashSet pkAttrs = new HashSet();
        pkAttrs.add("companyCodeSys01SAL06");
        pkAttrs.add("chargeCodeSAL06");

        HashMap attr2dbFields = new HashMap();
        attr2dbFields.put("companyCodeSys01SAL06", "COMPANY_CODE_SYS01");
        attr2dbFields.put("chargeCodeSAL06", "CHARGE_CODE");
        attr2dbFields.put("progressiveSys10SAL06", "PROGRESSIVE_SYS10");
        attr2dbFields.put("valueSAL06", "VALUE");
        attr2dbFields.put("percSAL06", "PERC");
        attr2dbFields.put("vatCodeReg01SAL06", "VAT_CODE_REG01");
        attr2dbFields.put("currencyCodeReg03SAL06", "CURRENCY_CODE_REG03");

        res =
            new CustomizeQueryUtil()
                .updateTable(
                    conn,
                    new UserSessionParameters(username),
                    pkAttrs,
                    oldVO,
                    newVO,
                    "SAL06_CHARGES",
                    attr2dbFields,
                    "Y",
                    "N",
                    null,
                    true,
                    customizedFields);
        if (res.isError()) {
          throw new Exception(res.getErrorMessage());
        }
      }

      return new VOListResponse(newVOs, false, newVOs.size());
    } catch (Throwable ex) {
      Logger.error(
          username,
          this.getClass().getName(),
          "executeCommand",
          "Error while updating existing charges",
          ex);
      try {
        if (this.conn == null && conn != null)
          // rollback only local connection
          conn.rollback();
      } catch (Exception ex3) {
      }

      throw new Exception(ex.getMessage());
    } finally {
      try {
        if (this.conn == null && conn != null) {
          // close only local connection
          conn.commit();
          conn.close();
        }

      } catch (Exception exx) {
      }
    }
  }
  /**
   * Check if components required by specified products are available.
   *
   * @param products list of ProdOrderProductVO objects
   * @params compAltComps collection of <component item code,HashSet of alternative component item
   *     codes>; filled by this method (and given back by reference)
   * @return VOListResponse of ProdOrderComponentVO objects
   */
  public final Response checkComponentsAvailability(
      Connection conn,
      Hashtable compAltComps,
      ArrayList products,
      UserSessionParameters userSessionPars,
      HttpServletRequest request,
      HttpServletResponse response,
      HttpSession userSession,
      ServletContext context) {
    String serverLanguageId = ((JAIOUserSessionParameters) userSessionPars).getServerLanguageId();
    try {

      // retrieve internationalization settings (Resources object)...
      ServerResourcesFactory factory =
          (ServerResourcesFactory) context.getAttribute(Controller.RESOURCES_FACTORY);
      Resources resources = factory.getResources(userSessionPars.getLanguageId());

      if (products.size() == 0) {
        return new VOListResponse(new ArrayList(), false, 0);
      }

      // fill in comps hashtable with the collection of required components...
      ItemPK pk = null;
      ProdOrderProductVO prodVO = null;
      ArrayList components = null;
      MaterialVO compVO = null;
      Response res = null;
      ProdOrderComponentVO componentVO = null;
      Hashtable comps =
          new Hashtable(); // collection of <component item code,ProdOrderComponentVO object>
      for (int i = 0; i < products.size(); i++) {
        // retrieve bill of materials for each product...
        prodVO = (ProdOrderProductVO) products.get(i);
        pk = new ItemPK(prodVO.getCompanyCodeSys01DOC23(), prodVO.getItemCodeItm01DOC23());
        res =
            bean.getBillOfMaterials(
                conn, pk, userSessionPars, request, response, userSession, context);
        if (res.isError()) {
          return res;
        }

        // extract components only (leaf nodes)...
        components =
            getComponents(
                (DefaultMutableTreeNode) ((TreeModel) ((VOResponse) res).getVo()).getRoot());
        for (int j = 0; j < components.size(); j++) {
          compVO = (MaterialVO) components.get(j);
          componentVO = (ProdOrderComponentVO) comps.get(compVO.getItemCodeItm01ITM03());
          if (componentVO == null) {
            componentVO = new ProdOrderComponentVO();
            comps.put(compVO.getItemCodeItm01ITM03(), componentVO);
            componentVO.setAvailableQty(new BigDecimal(0));
            componentVO.setCompanyCodeSys01DOC24(compVO.getCompanyCodeSys01ITM03());
            componentVO.setDescriptionSYS10(compVO.getDescriptionSYS10());
            componentVO.setDocNumberDOC24(prodVO.getDocNumberDOC23());
            componentVO.setDocYearDOC24(prodVO.getDocYearDOC23());
            componentVO.setItemCodeItm01DOC24(compVO.getItemCodeItm01ITM03());
            componentVO.setMinSellingQtyUmCodeReg02ITM01(compVO.getMinSellingQtyUmCodeReg02ITM01());
            componentVO.setQtyDOC24(new BigDecimal(0));
          }
          componentVO.setQtyDOC24(
              componentVO.getQtyDOC24().add(compVO.getQtyITM03().multiply(prodVO.getQtyDOC23())));
        }
      }

      // check components availability in the specified warehouse...
      Enumeration en = comps.keys();
      GridParams gridParams = new GridParams();
      gridParams
          .getOtherGridParams()
          .put(ApplicationConsts.COMPANY_CODE_SYS01, prodVO.getCompanyCodeSys01DOC23());
      gridParams
          .getOtherGridParams()
          .put(ApplicationConsts.WAREHOUSE_CODE, prodVO.getWarehouseCodeWar01DOC22());
      gridParams.getOtherGridParams().put(ApplicationConsts.LOAD_ALL, Boolean.TRUE);
      ItemAvailabilityVO availVO = null;
      BigDecimal availability, altAvailability, delta;
      String itemCode = null;
      ArrayList list, availList;
      AltComponentVO altVO = null;
      ArrayList alternativeComps = new ArrayList();
      ArrayList compsToRemove = new ArrayList();
      ProdOrderComponentVO altComponentVO = null;
      HashSet altCodes = null; // list of alternative component item codes...
      BigDecimal altQty = null;
      while (en.hasMoreElements()) {
        itemCode = en.nextElement().toString();
        componentVO = (ProdOrderComponentVO) comps.get(itemCode);

        gridParams
            .getOtherGridParams()
            .put(
                ApplicationConsts.ITEM_PK, new ItemPK(prodVO.getCompanyCodeSys01DOC23(), itemCode));
        res =
            avail.executeCommand(
                gridParams, userSessionPars, request, response, userSession, context);
        if (res.isError()) return res;

        availList = ((VOListResponse) res).getRows();
        componentVO.setAvailabilities(availList);
        availability = new BigDecimal(0);
        for (int i = 0; i < availList.size(); i++) {
          availVO = (ItemAvailabilityVO) availList.get(i);
          availability = availability.add(availVO.getAvailableQtyWAR03());
        }
        componentVO.setAvailableQty(availability);

        if (componentVO.getQtyDOC24().doubleValue() > componentVO.getAvailableQty().doubleValue()) {
          // check if there exist some alternative component...
          res =
              altComps.executeCommand(
                  gridParams, userSessionPars, request, response, userSession, context);
          if (res.isError()) return res;
          list = ((VOListResponse) res).getRows();
          for (int i = 0; i < list.size(); i++) {
            altVO = (AltComponentVO) list.get(i);
            gridParams
                .getOtherGridParams()
                .put(
                    ApplicationConsts.ITEM_PK,
                    new ItemPK(prodVO.getCompanyCodeSys01DOC23(), altVO.getItemCodeItm01ITM04()));
            res =
                avail.executeCommand(
                    gridParams, userSessionPars, request, response, userSession, context);
            if (res.isError()) return res;
            availList = ((VOListResponse) res).getRows();
            altAvailability = new BigDecimal(0);
            for (int j = 0; j < availList.size(); j++) {
              availVO = (ItemAvailabilityVO) availList.get(j);
              altAvailability = altAvailability.add(availVO.getAvailableQtyWAR03());
            }
            if (altAvailability.doubleValue() > 0) {
              altComponentVO = new ProdOrderComponentVO();
              altComponentVO.setAvailabilities(availList);
              altComponentVO.setAvailableQty(altAvailability);
              altComponentVO.setCompanyCodeSys01DOC24(altVO.getCompanyCodeSys01ITM04());
              altComponentVO.setDescriptionSYS10(altVO.getDescriptionSYS10());
              altComponentVO.setDocNumberDOC24(prodVO.getDocNumberDOC23());
              altComponentVO.setDocYearDOC24(prodVO.getDocYearDOC23());
              altComponentVO.setItemCodeItm01DOC24(altVO.getItemCodeItm01ITM04());
              altComponentVO.setMinSellingQtyUmCodeReg02ITM01(
                  altVO.getMinSellingQtyUmCodeReg02ITM01());
              altQty =
                  conv.convertQty(
                      altVO.getMinSellingQtyUmCodeReg02ITM01(),
                      componentVO.getMinSellingQtyUmCodeReg02ITM01(),
                      altAvailability,
                      userSessionPars,
                      request,
                      response,
                      userSession,
                      context);
              if (componentVO.getQtyDOC24().subtract(availability).doubleValue()
                  > altQty.doubleValue()) {
                delta = altQty;
                altComponentVO.setQtyDOC24(altAvailability);
              } else {
                delta = componentVO.getQtyDOC24();
                altComponentVO.setQtyDOC24(
                    conv.convertQty(
                        componentVO.getMinSellingQtyUmCodeReg02ITM01(),
                        altVO.getMinSellingQtyUmCodeReg02ITM01(),
                        delta,
                        userSessionPars,
                        request,
                        response,
                        userSession,
                        context));
              }
              componentVO.setQtyDOC24(componentVO.getQtyDOC24().subtract(delta));
              alternativeComps.add(altComponentVO);

              altCodes = (HashSet) compAltComps.get(itemCode);
              if (altCodes == null) {
                altCodes = new HashSet();
                compAltComps.put(itemCode, altCodes);
              }
              altCodes.add(altVO.getItemCodeItm01ITM04());

              if (componentVO.getQtyDOC24().doubleValue() == 0) {
                compsToRemove.add(componentVO);
                break;
              }
              if (componentVO.getQtyDOC24().subtract(availability).doubleValue() == 0) break;
            }
          }
        }
      }

      list = new ArrayList(comps.values());
      list.addAll(alternativeComps);
      list.removeAll(compsToRemove);
      return new VOListResponse(list, false, list.size());
    } catch (Throwable ex) {
      Logger.error(
          userSessionPars.getUsername(),
          this.getClass().getName(),
          "checkComponentsAvailability",
          "Error while retrieving components availability for the specified production order",
          ex);
      return new ErrorResponse(ex.getMessage());
    }
  }
  /** Business logic to execute. */
  public VOListResponse loadSupplierPriceItems(
      GridParams pars, String serverLanguageId, String username, ArrayList customizedFields)
      throws Throwable {
    PreparedStatement pstmt = null;
    Connection conn = null;
    try {
      if (this.conn == null) conn = getConn();
      else conn = this.conn;

      BigDecimal rootProgressiveHIE01 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.ROOT_PROGRESSIVE_HIE01);
      BigDecimal progressiveHIE01 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.PROGRESSIVE_HIE01);
      BigDecimal progressiveHIE02 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.PROGRESSIVE_HIE02);
      BigDecimal progressiveREG04 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.PROGRESSIVE_REG04);
      String companyCodeSYS01 =
          (String) pars.getOtherGridParams().get(ApplicationConsts.COMPANY_CODE_SYS01);
      String pricelistCodePUR03 =
          (String) pars.getOtherGridParams().get(ApplicationConsts.PRICELIST);

      CompanyHierarchyLevelVO vo =
          (CompanyHierarchyLevelVO) pars.getOtherGridParams().get(ApplicationConsts.TREE_FILTER);
      if (vo != null) {
        progressiveHIE01 = vo.getProgressiveHIE01();
        progressiveHIE02 = vo.getProgressiveHie02HIE01();
      }

      String sql =
          "select PUR02_SUPPLIER_ITEMS.COMPANY_CODE_SYS01,PUR02_SUPPLIER_ITEMS.ITEM_CODE_ITM01,PUR02_SUPPLIER_ITEMS.SUPPLIER_ITEM_CODE,PUR02_SUPPLIER_ITEMS.PROGRESSIVE_REG04,"
              + "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE02,PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE01,PUR02_SUPPLIER_ITEMS.MIN_PURCHASE_QTY,PUR02_SUPPLIER_ITEMS.MULTIPLE_QTY,"
              + "PUR02_SUPPLIER_ITEMS.UM_CODE_REG02,PUR02_SUPPLIER_ITEMS.ENABLED,SYS10_COMPANY_TRANSLATIONS.DESCRIPTION,REG02_MEASURE_UNITS.DECIMALS,"
              + "ITM01_ITEMS.VAT_CODE_REG01,SYS10_VAT.DESCRIPTION,REG01_VATS.DEDUCTIBLE,REG01_VATS.VALUE,"
              + "PUR04_SUPPLIER_PRICES.VALUE,PUR04_SUPPLIER_PRICES.START_DATE,PUR04_SUPPLIER_PRICES.END_DATE,"
              + "ITM01_ITEMS.USE_VARIANT_1,ITM01_ITEMS.USE_VARIANT_2,ITM01_ITEMS.USE_VARIANT_3,ITM01_ITEMS.USE_VARIANT_4,ITM01_ITEMS.USE_VARIANT_5, "
              + "ITM01_ITEMS.NO_WAREHOUSE_MOV "
              + " from PUR02_SUPPLIER_ITEMS,SYS10_COMPANY_TRANSLATIONS,ITM01_ITEMS,REG02_MEASURE_UNITS,SYS10_TRANSLATIONS SYS10_VAT,REG01_VATS,PUR04_SUPPLIER_PRICES where "
              + "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE02=? and "
              + "PUR02_SUPPLIER_ITEMS.UM_CODE_REG02=REG02_MEASURE_UNITS.UM_CODE and "
              + "PUR02_SUPPLIER_ITEMS.COMPANY_CODE_SYS01=ITM01_ITEMS.COMPANY_CODE_SYS01 and "
              + "PUR02_SUPPLIER_ITEMS.ITEM_CODE_ITM01=ITM01_ITEMS.ITEM_CODE and "
              + "ITM01_ITEMS.COMPANY_CODE_SYS01=SYS10_COMPANY_TRANSLATIONS.COMPANY_CODE_SYS01 and "
              + "ITM01_ITEMS.PROGRESSIVE_SYS10=SYS10_COMPANY_TRANSLATIONS.PROGRESSIVE and "
              + "SYS10_COMPANY_TRANSLATIONS.LANGUAGE_CODE=? and "
              + "PUR02_SUPPLIER_ITEMS.COMPANY_CODE_SYS01 = ? and "
              + "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_REG04=? and "
              + "PUR02_SUPPLIER_ITEMS.ENABLED='Y' and "
              + "ITM01_ITEMS.VAT_CODE_REG01=REG01_VATS.VAT_CODE and "
              + "REG01_VATS.PROGRESSIVE_SYS10=SYS10_VAT.PROGRESSIVE and "
              + "SYS10_VAT.LANGUAGE_CODE=? and "
              + "PUR02_SUPPLIER_ITEMS.COMPANY_CODE_SYS01=PUR04_SUPPLIER_PRICES.COMPANY_CODE_SYS01 and "
              + "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_REG04=PUR04_SUPPLIER_PRICES.PROGRESSIVE_REG04 and "
              + "PUR02_SUPPLIER_ITEMS.ITEM_CODE_ITM01=PUR04_SUPPLIER_PRICES.ITEM_CODE_ITM01 and "
              + "PUR04_SUPPLIER_PRICES.PRICELIST_CODE_PUR03=? and "
              + "PUR04_SUPPLIER_PRICES.START_DATE<=? and "
              + "PUR04_SUPPLIER_PRICES.END_DATE>? ";

      if (rootProgressiveHIE01 == null || !rootProgressiveHIE01.equals(progressiveHIE01)) {
        // retrieve all subnodes of the specified node...
        pstmt =
            conn.prepareStatement(
                "select HIE01_COMPANY_LEVELS.PROGRESSIVE,HIE01_COMPANY_LEVELS.PROGRESSIVE_HIE01,HIE01_COMPANY_LEVELS.LEV from HIE01_COMPANY_LEVELS "
                    + "where COMPANY_CODE_SYS01='"
                    + companyCodeSYS01
                    + "' and ENABLED='Y' and PROGRESSIVE_HIE02=? and PROGRESSIVE>=? "
                    + "order by LEV,PROGRESSIVE_HIE01,PROGRESSIVE");
        pstmt.setBigDecimal(1, progressiveHIE02);
        pstmt.setBigDecimal(2, progressiveHIE01);
        ResultSet rset = pstmt.executeQuery();

        HashSet currentLevelNodes = new HashSet();
        HashSet newLevelNodes = new HashSet();
        String nodes = "";
        int currentLevel = -1;
        while (rset.next()) {
          if (currentLevel != rset.getInt(3)) {
            // next level...
            currentLevel = rset.getInt(3);
            currentLevelNodes = newLevelNodes;
            newLevelNodes = new HashSet();
          }
          if (rset.getBigDecimal(1).equals(progressiveHIE01)) {
            newLevelNodes.add(rset.getBigDecimal(1));
            nodes += rset.getBigDecimal(1) + ",";
          } else if (currentLevelNodes.contains(rset.getBigDecimal(2))) {
            newLevelNodes.add(rset.getBigDecimal(1));
            nodes += rset.getBigDecimal(1) + ",";
          }
        }
        rset.close();
        pstmt.close();
        if (nodes.length() > 0) nodes = nodes.substring(0, nodes.length() - 1);
        if (rootProgressiveHIE01 != null || nodes.length() > 0)
          sql += " and PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE01 in (" + nodes + ")";
      }

      Map attribute2dbField = new HashMap();
      attribute2dbField.put("companyCodeSys01PUR02", "PUR02_SUPPLIER_ITEMS.COMPANY_CODE_SYS01");
      attribute2dbField.put("itemCodeItm01PUR02", "PUR02_SUPPLIER_ITEMS.ITEM_CODE_ITM01");
      attribute2dbField.put("supplierItemCodePUR02", "PUR02_SUPPLIER_ITEMS.SUPPLIER_ITEM_CODE");
      attribute2dbField.put("progressiveReg04PUR02", "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_REG04");
      attribute2dbField.put("progressiveHie02PUR02", "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE02");
      attribute2dbField.put("progressiveHie01PUR02", "PUR02_SUPPLIER_ITEMS.PROGRESSIVE_HIE01");
      attribute2dbField.put("minPurchaseQtyPUR02", "PUR02_SUPPLIER_ITEMS.MIN_PURCHASE_QTY");
      attribute2dbField.put("multipleQtyPUR02", "PUR02_SUPPLIER_ITEMS.MULTIPLE_QTY");
      attribute2dbField.put("umCodeReg02PUR02", "PUR02_SUPPLIER_ITEMS.UM_CODE_REG02");
      attribute2dbField.put("enabledPUR02", "PUR02_SUPPLIER_ITEMS.ENABLED");
      attribute2dbField.put("descriptionSYS10", "SYS10_COMPANY_TRANSLATIONS.DESCRIPTION");
      attribute2dbField.put("decimalsREG02", "REG02_MEASURE_UNITS.DECIMALS");

      attribute2dbField.put("vatCodeReg01ITM01", "ITM01_ITEMS.VAT_CODE_REG01");
      attribute2dbField.put("vatDescriptionSYS10", "SYS10_VAT.DESCRIPTION");
      attribute2dbField.put("deductibleREG01", "REG01_VATS.DEDUCTIBLE");
      attribute2dbField.put("valueREG01", "REG01_VATS.VALUE");
      attribute2dbField.put("valuePUR04", "PUR04_SUPPLIER_PRICES.VALUE");
      attribute2dbField.put("startDatePUR04", "PUR04_SUPPLIER_PRICES.START_DATE");
      attribute2dbField.put("endDatePUR04", "PUR04_SUPPLIER_PRICES.END_DATE");

      attribute2dbField.put("useVariant1ITM01", "ITM01_ITEMS.USE_VARIANT_1");
      attribute2dbField.put("useVariant2ITM01", "ITM01_ITEMS.USE_VARIANT_2");
      attribute2dbField.put("useVariant3ITM01", "ITM01_ITEMS.USE_VARIANT_3");
      attribute2dbField.put("useVariant4ITM01", "ITM01_ITEMS.USE_VARIANT_4");
      attribute2dbField.put("useVariant5ITM01", "ITM01_ITEMS.USE_VARIANT_5");

      attribute2dbField.put("noWarehouseMovITM01", "ITM01_ITEMS.NO_WAREHOUSE_MOV");

      ArrayList values = new ArrayList();
      values.add(progressiveHIE02);
      values.add(serverLanguageId);
      values.add(companyCodeSYS01);
      values.add(progressiveREG04);
      values.add(serverLanguageId);
      values.add(pricelistCodePUR03);
      values.add(new java.sql.Date(System.currentTimeMillis()));
      values.add(new java.sql.Date(System.currentTimeMillis()));

      // read from PUR02 table...
      Response answer =
          CustomizeQueryUtil.getQuery(
              conn,
              new UserSessionParameters(username),
              sql,
              values,
              attribute2dbField,
              SupplierPriceItemVO.class,
              "Y",
              "N",
              null,
              pars,
              50,
              true,
              customizedFields);
      if (answer.isError()) throw new Exception(answer.getErrorMessage());
      else return (VOListResponse) answer;

    } catch (Throwable ex) {
      Logger.error(
          username,
          this.getClass().getName(),
          "executeCommand",
          "Error while fetching supplier items list",
          ex);
      throw new Exception(ex.getMessage());
    } finally {
      try {
        pstmt.close();
      } catch (Exception exx) {
      }
      try {
        if (this.conn == null && conn != null) {
          // close only local connection
          conn.commit();
          conn.close();
        }

      } catch (Exception exx) {
      }
    }
  }
  /** Business logic to execute. */
  public final Response executeCommand(
      Object inputPar,
      UserSessionParameters userSessionPars,
      HttpServletRequest request,
      HttpServletResponse response,
      HttpSession userSession,
      ServletContext context) {
    String serverLanguageId = ((JAIOUserSessionParameters) userSessionPars).getServerLanguageId();

    PreparedStatement pstmt = null;
    Connection conn = null;
    try {
      conn = ConnectionManager.getConnection(context);

      // fires the GenericEvent.CONNECTION_CREATED event...
      EventsManager.getInstance()
          .processEvent(
              new GenericEvent(
                  this,
                  getRequestName(),
                  GenericEvent.CONNECTION_CREATED,
                  (JAIOUserSessionParameters) userSessionPars,
                  request,
                  response,
                  userSession,
                  context,
                  conn,
                  inputPar,
                  null));

      GridParams pars = (GridParams) inputPar;

      BigDecimal rootProgressiveHIE01 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.ROOT_PROGRESSIVE_HIE01);
      BigDecimal progressiveHIE01 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.PROGRESSIVE_HIE01);
      BigDecimal progressiveHIE02 =
          (BigDecimal) pars.getOtherGridParams().get(ApplicationConsts.PROGRESSIVE_HIE02);
      Boolean productsOnly =
          (Boolean) pars.getOtherGridParams().get(ApplicationConsts.PRODUCTS_ONLY);
      Boolean compsOnly =
          (Boolean) pars.getOtherGridParams().get(ApplicationConsts.COMPONENTS_ONLY);

      HierarchyLevelVO vo =
          (HierarchyLevelVO) pars.getOtherGridParams().get(ApplicationConsts.TREE_FILTER);
      if (vo != null) {
        progressiveHIE01 = vo.getProgressiveHIE01();
        progressiveHIE02 = vo.getProgressiveHie02HIE01();
      }

      // retrieve companies list...
      ArrayList companiesList =
          ((JAIOUserSessionParameters) userSessionPars).getCompanyBa().getCompaniesList("ITM01");
      String companies = "";
      for (int i = 0; i < companiesList.size(); i++)
        companies += "'" + companiesList.get(i).toString() + "',";
      companies = companies.substring(0, companies.length() - 1);

      String sql =
          "select ITM01_ITEMS.COMPANY_CODE_SYS01,ITM01_ITEMS.ITEM_CODE,SYS10_TRANSLATIONS.DESCRIPTION,ITM01_ITEMS.PROGRESSIVE_HIE02,ITM01_ITEMS.MIN_SELLING_QTY_UM_CODE_REG02,"
              + "ITM01_ITEMS.PROGRESSIVE_HIE01,ITM01_ITEMS.SERIAL_NUMBER_REQUIRED,REG02_MEASURE_UNITS.DECIMALS "
              + " from ITM01_ITEMS,SYS10_TRANSLATIONS,REG02_MEASURE_UNITS where "
              + "ITM01_ITEMS.PROGRESSIVE_HIE02=? and "
              + "ITM01_ITEMS.PROGRESSIVE_SYS10=SYS10_TRANSLATIONS.PROGRESSIVE and "
              + "SYS10_TRANSLATIONS.LANGUAGE_CODE=? and "
              + "ITM01_ITEMS.COMPANY_CODE_SYS01 in ("
              + companies
              + ") and "
              + "ITM01_ITEMS.ENABLED='Y' and "
              + "ITM01_ITEMS.MIN_SELLING_QTY_UM_CODE_REG02=REG02_MEASURE_UNITS.UM_CODE ";

      if (productsOnly != null && productsOnly.booleanValue())
        sql += " and ITM01_ITEMS.MANUFACTURE_CODE_PRO01 is not null ";

      if (compsOnly != null && compsOnly.booleanValue())
        sql += " and ITM01_ITEMS.MANUFACTURE_CODE_PRO01 is null ";

      if (rootProgressiveHIE01 == null || !rootProgressiveHIE01.equals(progressiveHIE01)) {
        // retrieve all subnodes of the specified node...
        pstmt =
            conn.prepareStatement(
                "select HIE01_LEVELS.PROGRESSIVE,HIE01_LEVELS.PROGRESSIVE_HIE01,HIE01_LEVELS.LEV from HIE01_LEVELS "
                    + "where ENABLED='Y' and PROGRESSIVE_HIE02=? and PROGRESSIVE>=? "
                    + "order by LEV,PROGRESSIVE_HIE01,PROGRESSIVE");
        pstmt.setBigDecimal(1, progressiveHIE02);
        pstmt.setBigDecimal(2, progressiveHIE01);
        ResultSet rset = pstmt.executeQuery();

        HashSet currentLevelNodes = new HashSet();
        HashSet newLevelNodes = new HashSet();
        String nodes = "";
        int currentLevel = -1;
        while (rset.next()) {
          if (currentLevel != rset.getInt(3)) {
            // next level...
            currentLevel = rset.getInt(3);
            currentLevelNodes = newLevelNodes;
            newLevelNodes = new HashSet();
          }
          if (rset.getBigDecimal(1).equals(progressiveHIE01)) {
            newLevelNodes.add(rset.getBigDecimal(1));
            nodes += rset.getBigDecimal(1) + ",";
          } else if (currentLevelNodes.contains(rset.getBigDecimal(2))) {
            newLevelNodes.add(rset.getBigDecimal(1));
            nodes += rset.getBigDecimal(1) + ",";
          }
        }
        rset.close();
        pstmt.close();
        if (nodes.length() > 0) nodes = nodes.substring(0, nodes.length() - 1);
        sql += " and PROGRESSIVE_HIE01 in (" + nodes + ")";
      }

      Map attribute2dbField = new HashMap();
      attribute2dbField.put("companyCodeSys01ITM01", "ITM01_ITEMS.COMPANY_CODE_SYS01");
      attribute2dbField.put("itemCodeITM01", "ITM01_ITEMS.ITEM_CODE");
      attribute2dbField.put("descriptionSYS10", "SYS10_TRANSLATIONS.DESCRIPTION");
      attribute2dbField.put("progressiveHie02ITM01", "ITM01_ITEMS.PROGRESSIVE_HIE02");
      attribute2dbField.put(
          "minSellingQtyUmCodeReg02ITM01", "ITM01_ITEMS.MIN_SELLING_QTY_UM_CODE_REG02");
      attribute2dbField.put("progressiveHie01ITM01", "ITM01_ITEMS.PROGRESSIVE_HIE01");
      attribute2dbField.put("serialNumberRequiredITM01", "ITM01_ITEMS.SERIAL_NUMBER_REQUIRED");
      attribute2dbField.put("decimalsREG02", "REG02_MEASURE_UNITS.DECIMALS");

      ArrayList values = new ArrayList();
      values.add(progressiveHIE02);
      values.add(serverLanguageId);

      // read from ITM01 table...
      Response answer =
          QueryUtil.getQuery(
              conn,
              userSessionPars,
              sql,
              values,
              attribute2dbField,
              GridItemVO.class,
              "Y",
              "N",
              context,
              pars,
              50,
              true);

      // fires the GenericEvent.BEFORE_COMMIT event...
      EventsManager.getInstance()
          .processEvent(
              new GenericEvent(
                  this,
                  getRequestName(),
                  GenericEvent.BEFORE_COMMIT,
                  (JAIOUserSessionParameters) userSessionPars,
                  request,
                  response,
                  userSession,
                  context,
                  conn,
                  inputPar,
                  answer));
      return answer;

    } catch (Throwable ex) {
      Logger.error(
          userSessionPars.getUsername(),
          this.getClass().getName(),
          "executeCommand",
          "Error while fetching items list",
          ex);
      return new ErrorResponse(ex.getMessage());
    } finally {
      try {
        pstmt.close();
      } catch (Exception ex2) {
      }
      try {
        ConnectionManager.releaseConnection(conn, context);
      } catch (Exception ex1) {
      }
    }
  }
  /** Business logic to execute. */
  public VOListResponse loadOutDeliveryNotesForSaleDoc(
      GridParams pars, String serverLanguageId, String username, ArrayList companiesList)
      throws Throwable {
    PreparedStatement pstmt = null;
    Connection conn = null;
    try {
      if (this.conn == null) conn = getConn();
      else conn = this.conn;

      // retrieve companies list...
      String companies = "";
      for (int i = 0; i < companiesList.size(); i++)
        companies += "'" + companiesList.get(i).toString() + "',";
      companies = companies.substring(0, companies.length() - 1);

      String sql =
          "select DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01,DOC08_DELIVERY_NOTES.DOC_TYPE,"
              + "DOC08_DELIVERY_NOTES.DOC_YEAR,DOC08_DELIVERY_NOTES.DOC_NUMBER,DOC08_DELIVERY_NOTES.DOC_DATE, "
              + "DOC08_DELIVERY_NOTES.DESTINATION_CODE_REG18,DOC08_DELIVERY_NOTES.DESCRIPTION,"
              + "DOC08_DELIVERY_NOTES.DOC_SEQUENCE "
              + " from DOC08_DELIVERY_NOTES where "
              + "DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01 in ("
              + companies
              + ") and "
              + "DOC08_DELIVERY_NOTES.ENABLED='Y' and "
              + "DOC08_DELIVERY_NOTES.DOC_TYPE=? and "
              + "DOC08_DELIVERY_NOTES.DOC_STATE=? and "
              + "(DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01,DOC08_DELIVERY_NOTES.DOC_TYPE,DOC08_DELIVERY_NOTES.DOC_YEAR,DOC08_DELIVERY_NOTES.DOC_NUMBER) "
              + " in (select DOC10_OUT_DELIVERY_NOTE_ITEMS.COMPANY_CODE_SYS01,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_TYPE,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_YEAR,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_NUMBER "
              + " from DOC10_OUT_DELIVERY_NOTE_ITEMS where "
              + " DOC10_OUT_DELIVERY_NOTE_ITEMS.COMPANY_CODE_SYS01=? and "
              + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_TYPE_DOC01=? and "
              + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_YEAR_DOC01=? and "
              + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_NUMBER_DOC01=? ";

      DetailSaleDocVO docVO =
          (DetailSaleDocVO)
              pars.getOtherGridParams().get(ApplicationConsts.SALE_DOC_VO); // invoice document...
      if (docVO.getDocNumberDOC01() == null)
        sql +=
            " and DOC10_OUT_DELIVERY_NOTE_ITEMS.QTY-DOC10_OUT_DELIVERY_NOTE_ITEMS.INVOICE_QTY>0)";
      else sql += ")";

      Map attribute2dbField = new HashMap();
      attribute2dbField.put("companyCodeSys01DOC08", "DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01");
      attribute2dbField.put("docTypeDOC08", "DOC08_DELIVERY_NOTES.DOC_TYPE");
      attribute2dbField.put("docYearDOC08", "DOC08_DELIVERY_NOTES.DOC_YEAR");
      attribute2dbField.put("docNumberDOC08", "DOC08_DELIVERY_NOTES.DOC_NUMBER");
      attribute2dbField.put("docDateDOC08", "DOC08_DELIVERY_NOTES.DOC_DATE");
      attribute2dbField.put(
          "destinationCodeReg18DOC08", "DOC08_DELIVERY_NOTES.DESTINATION_CODE_REG18");
      attribute2dbField.put("descriptionDOC08", "DOC08_DELIVERY_NOTES.DESCRIPTION");
      attribute2dbField.put("docSequenceDOC08", "DOC08_DELIVERY_NOTES.DOC_SEQUENCE");

      ArrayList values = new ArrayList();
      values.add(ApplicationConsts.OUT_DELIVERY_NOTE_DOC_TYPE);
      values.add(ApplicationConsts.CLOSED);
      values.add(docVO.getCompanyCodeSys01DOC01());
      values.add(docVO.getDocTypeDoc01DOC01());
      values.add(docVO.getDocYearDoc01DOC01());
      values.add(docVO.getDocNumberDoc01DOC01());

      // read from DOC08 table...
      Response res =
          QueryUtil.getQuery(
              conn,
              new UserSessionParameters(username),
              sql,
              values,
              attribute2dbField,
              OutDeliveryNotesVO.class,
              "Y",
              "N",
              null,
              pars,
              true);

      if (res.isError()) throw new Exception(res.getErrorMessage());

      // check if the invoice document has been already created and there exists delivery notes
      // linked to it...
      if (docVO.getDocNumberDOC01() != null) {
        pstmt =
            conn.prepareStatement(
                "select DOC08_DELIVERY_NOTES.DOC_NUMBER from DOC08_DELIVERY_NOTES where "
                    + "DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01 in ("
                    + companies
                    + ") and "
                    + "DOC08_DELIVERY_NOTES.ENABLED='Y' and "
                    + "DOC08_DELIVERY_NOTES.DOC_TYPE=? and "
                    + "DOC08_DELIVERY_NOTES.DOC_STATE=? and "
                    + "(DOC08_DELIVERY_NOTES.COMPANY_CODE_SYS01,DOC08_DELIVERY_NOTES.DOC_TYPE,DOC08_DELIVERY_NOTES.DOC_YEAR,DOC08_DELIVERY_NOTES.DOC_NUMBER) "
                    + " in (select DOC10_OUT_DELIVERY_NOTE_ITEMS.COMPANY_CODE_SYS01,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_TYPE,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_YEAR,DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_NUMBER "
                    + " from DOC10_OUT_DELIVERY_NOTE_ITEMS,DOC02_SELLING_ITEMS where "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.COMPANY_CODE_SYS01=? and "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_TYPE_DOC01=? and "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_YEAR_DOC01=? and "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.DOC_NUMBER_DOC01=? and "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.COMPANY_CODE_SYS01=DOC02_SELLING_ITEMS.COMPANY_CODE_SYS01 and "
                    + " DOC02_SELLING_ITEMS.DOC_TYPE=? and "
                    + " DOC02_SELLING_ITEMS.DOC_YEAR=? and "
                    + " DOC02_SELLING_ITEMS.DOC_NUMBER=? and "
                    + " DOC10_OUT_DELIVERY_NOTE_ITEMS.ITEM_CODE_ITM01=DOC02_SELLING_ITEMS.ITEM_CODE_ITM01)");

        pstmt.setString(1, ApplicationConsts.OUT_DELIVERY_NOTE_DOC_TYPE);
        pstmt.setString(2, ApplicationConsts.CLOSED);
        pstmt.setString(3, docVO.getCompanyCodeSys01DOC01());
        pstmt.setString(4, docVO.getDocTypeDoc01DOC01());
        pstmt.setBigDecimal(5, docVO.getDocYearDoc01DOC01());
        pstmt.setBigDecimal(6, docVO.getDocNumberDoc01DOC01());
        pstmt.setString(7, docVO.getDocTypeDOC01());
        pstmt.setBigDecimal(8, docVO.getDocYearDOC01());
        pstmt.setBigDecimal(9, docVO.getDocNumberDOC01());

        HashSet docNumberDOC08s = new HashSet();
        ResultSet rset = pstmt.executeQuery();
        while (rset.next()) docNumberDOC08s.add(rset.getBigDecimal(1));
        rset.close();

        java.util.List rows = ((VOListResponse) res).getRows();
        OutDeliveryNotesVO vo = null;
        for (int i = 0; i < rows.size(); i++) {
          vo = (OutDeliveryNotesVO) rows.get(i);
          if (docNumberDOC08s.contains(vo.getDocNumberDOC08())) vo.setSelected(Boolean.TRUE);
        }
      }

      Response answer = res;
      if (answer.isError()) throw new Exception(answer.getErrorMessage());
      else return (VOListResponse) answer;
    } catch (Throwable ex) {
      Logger.error(
          username,
          this.getClass().getName(),
          "executeCommand",
          "Error while fetching out delivery notes list, related to the specified sale document",
          ex);
      throw new Exception(ex.getMessage());
    } finally {
      try {
        pstmt.close();
      } catch (Exception exx) {
      }
      try {
        if (this.conn == null && conn != null) {
          // close only local connection
          conn.commit();
          conn.close();
        }

      } catch (Exception exx) {
      }
    }
  }
  /** Business logic to execute. */
  public final Response executeCommand(
      Object inputPar,
      UserSessionParameters userSessionPars,
      HttpServletRequest request,
      HttpServletResponse response,
      HttpSession userSession,
      ServletContext context) {
    Connection conn = null;
    PreparedStatement pstmt = null;
    try {
      String serverLanguageId = ((JAIOUserSessionParameters) userSessionPars).getServerLanguageId();
      conn = ConnectionManager.getConnection(context);

      // fires the GenericEvent.CONNECTION_CREATED event...
      EventsManager.getInstance()
          .processEvent(
              new GenericEvent(
                  this,
                  getRequestName(),
                  GenericEvent.CONNECTION_CREATED,
                  (JAIOUserSessionParameters) userSessionPars,
                  request,
                  response,
                  userSession,
                  context,
                  conn,
                  inputPar,
                  null));

      ArrayList oldVOs = ((ArrayList[]) inputPar)[0];
      ArrayList newVOs = ((ArrayList[]) inputPar)[1];

      Map attribute2dbField = new HashMap();
      attribute2dbField.put("companyCodeSys01DOC20", "COMPANY_CODE_SYS01");
      attribute2dbField.put("progressiveDoc14DOC20", "PROGRESSIVE_DOC14");
      attribute2dbField.put("progressiveSys10DOC20", "PROGRESSIVE_SYS10");
      attribute2dbField.put("textValueDOC20", "TEXT_VALUE");
      attribute2dbField.put("numValueDOC20", "NUM_VALUE");
      attribute2dbField.put("dateValueDOC20", "DATE_VALUE");

      HashSet pkAttributes = new HashSet();
      pkAttributes.add("companyCodeSys01DOC20");
      pkAttributes.add("progressiveDoc14DOC20");
      pkAttributes.add("progressiveSys10DOC20");

      Response res = null;
      DocPropertyVO oldVO = null;
      DocPropertyVO newVO = null;

      pstmt =
          conn.prepareStatement(
              "select PROGRESSIVE_DOC14 from DOC20_DOC_PROPERTIES where "
                  + "COMPANY_CODE_SYS01=? and PROGRESSIVE_DOC14=? and PROGRESSIVE_SYS10=?");
      ResultSet rset = null;

      for (int i = 0; i < oldVOs.size(); i++) {
        oldVO = (DocPropertyVO) oldVOs.get(i);
        newVO = (DocPropertyVO) newVOs.get(i);

        // check if the record already exists: if it does not exist, then insert it...
        pstmt.setString(1, newVO.getCompanyCodeSys01DOC20());
        pstmt.setBigDecimal(2, newVO.getProgressiveDoc14DOC20());
        pstmt.setBigDecimal(3, newVO.getProgressiveSys10DOC20());
        rset = pstmt.executeQuery();
        if (rset.next()) {
          // the record exixts: it will be updated...
          res =
              QueryUtil.updateTable(
                  conn,
                  userSessionPars,
                  pkAttributes,
                  oldVO,
                  newVO,
                  "DOC20_DOC_PROPERTIES",
                  attribute2dbField,
                  "Y",
                  "N",
                  context,
                  true);
          if (res.isError()) {
            conn.rollback();
            return res;
          }
        } else {
          // the record does not exixt: it will be inserted...
          res =
              QueryUtil.insertTable(
                  conn,
                  userSessionPars,
                  newVO,
                  "DOC20_DOC_PROPERTIES",
                  attribute2dbField,
                  "Y",
                  "N",
                  context,
                  true);
          if (res.isError()) {
            conn.rollback();
            return res;
          }
        }
        rset.close();
      }

      Response answer = new VOListResponse(newVOs, false, newVOs.size());

      // fires the GenericEvent.BEFORE_COMMIT event...
      EventsManager.getInstance()
          .processEvent(
              new GenericEvent(
                  this,
                  getRequestName(),
                  GenericEvent.BEFORE_COMMIT,
                  (JAIOUserSessionParameters) userSessionPars,
                  request,
                  response,
                  userSession,
                  context,
                  conn,
                  inputPar,
                  answer));

      conn.commit();

      // fires the GenericEvent.AFTER_COMMIT event...
      EventsManager.getInstance()
          .processEvent(
              new GenericEvent(
                  this,
                  getRequestName(),
                  GenericEvent.AFTER_COMMIT,
                  (JAIOUserSessionParameters) userSessionPars,
                  request,
                  response,
                  userSession,
                  context,
                  conn,
                  inputPar,
                  answer));

      return answer;
    } catch (Throwable ex) {
      Logger.error(
          userSessionPars.getUsername(),
          this.getClass().getName(),
          "executeCommand",
          "Error while updating property values for the specified document",
          ex);
      try {
        conn.rollback();
      } catch (Exception ex3) {
      }
      return new ErrorResponse(ex.getMessage());
    } finally {
      try {
        pstmt.close();
      } catch (Exception ex2) {
      }
      try {
        ConnectionManager.releaseConnection(conn, context);
      } catch (Exception ex1) {
      }
    }
  }