/**
  * V5抛出异常工具1-保持异常链。
  *
  * <p><b>examples:</b>
  *
  * <p>使用示例
  *
  * <p><b>参数说明</b>
  *
  * @param e
  * @throws BusinessException
  *     <p>
  * @author czp
  * @time 2007-3-6 上午11:12:11
  */
 public static void throwBusinessException(Exception e) throws BusinessException {
   if (e instanceof BusinessException) throw (BusinessException) e;
   else {
     SCMEnv.out(e);
     throw new BusinessException(e.getMessage());
   }
 }
  public static void convertFreeValue(String pk_corp, IFreeField[] voItems)
      throws BusinessException {

    if (voItems == null || voItems.length == 0) return;

    HashMap<String, String> hmInv = new HashMap<String, String>();
    for (int i = 0; i < voItems.length; i++) {
      String invid = voItems[i].getInvBasID();
      hmInv.put(invid, invid);
    }

    String[] invids = new String[hmInv.size()];
    hmInv.keySet().toArray(invids);

    String sql =
        " select pk_invbasdoc,bas.free1,bas.free2,bas.free3,bas.free4,bas.free5 from bd_invbasdoc bas where  coalesce(bas.free1,bas.free2,bas.free3,bas.free4,bas.free5,'ZZ') !='ZZ' ";
    sql = sql + SQLUtil.formInSQL("pk_invbasdoc", invids);

    Object[] values = null;
    try {
      values = new SmartDMO().selectBy2(sql);
    } catch (Exception e) {
      SCMEnv.out(e);
      throw new BusinessException(e.getMessage());
    }

    FreeVO voFree = null;
    HashMap<String, FreeVO> hmFree = new HashMap<String, FreeVO>();
    if (values != null) {
      for (int i = 0; i < values.length; i++) {
        Object[] itemValues = (Object[]) values[i];

        voFree = new FreeVO();
        voFree.setPk_invbasdoc((String) itemValues[0]);
        voFree.setVfreeid1((String) itemValues[1]);
        voFree.setVfreeid2((String) itemValues[2]);
        voFree.setVfreeid3((String) itemValues[3]);
        voFree.setVfreeid4((String) itemValues[4]);
        voFree.setVfreeid5((String) itemValues[5]);

        hmFree.put(voFree.getPk_invbasdoc(), voFree);
      }
    }

    HashMap hmPara = getParaFreeAndPosMap(pk_corp);

    for (int i = 0; i < voItems.length; i++) {
      String invid = voItems[i].getInvBasID();
      Object[] ncvalues = new Object[5];
      Object[] retailvalues = voItems[i].getRetailFreeValue();

      if (hmFree.containsKey(invid)) {
        voFree = (FreeVO) hmFree.get(invid);

        int count = 0;
        for (int j = 0; j < 5; j++) {
          String key = (String) voFree.getAttributeValue("vfreeid" + String.valueOf(j + 1));
          if (key != null) count = count + 1;
          if (hmPara.containsKey(key)) {
            ncvalues[j] = retailvalues[((Integer) hmPara.get(key)).intValue() - 1];
          } else ncvalues[j] = null;
          if (ncvalues[j] != null) count = count - 1;
        }

        voItems[i].setNCFreeValue(ncvalues);

        if (count != 0) throw new BusinessException("请检查自由项值的正确性!");

      } else voItems[i].setNCFreeValue(null);
    }
  }
  /**
   * 存货与仓库属性匹配约束检查:非固定资产存货一定不能入资产仓(应税劳务和价格折扣属性的存货不检查)
   *
   * <p><b>examples:</b>
   *
   * <p>使用示例
   *
   * <p><b>参数说明</b>
   *
   * @param billVO:单据聚合VO
   * @param strBillType:单据类型
   * @throws BusinessException
   *     <p>
   * @author lixiaodong
   * @time 2007-5-30 下午01:54:12
   */
  public void checkStorAndInvIsCapital(AggregatedValueObject billVO, String strBillType)
      throws BusinessException {
    try {
      if (billVO == null || PuPubVO.getString_TrimZeroLenAsNull(strBillType) == null) {
        SCMEnv.out("传入参数不正确,直接返回");
        return;
      }

      Vector<String> vctBaseID = new Vector<String>(); // 存货基本档案ID
      Vector<String> vctWarehouseID = new Vector<String>(); // 收货仓库ID
      Object objInvBaseID = null;
      Object objWarehouseID = null;
      if (strBillType == nc.vo.scm.pu.BillTypeConst.PO_ORDER // 采购订单
          || strBillType == nc.vo.scm.pu.BillTypeConst.PO_PRAY // 采购请购单
          || strBillType == nc.vo.scm.pu.BillTypeConst.PO_ARRIVE) { // 采购到货单
        for (int i = 0; i < billVO.getChildrenVO().length; i++) {
          if (billVO.getChildrenVO()[i] != null) {
            objInvBaseID = billVO.getChildrenVO()[i].getAttributeValue("cbaseid");
            objWarehouseID = billVO.getChildrenVO()[i].getAttributeValue("cwarehouseid");
            if (PuPubVO.getString_TrimZeroLenAsNull(objInvBaseID) != null
                && PuPubVO.getString_TrimZeroLenAsNull(objWarehouseID) != null) {
              vctBaseID.add(objInvBaseID.toString());
              vctWarehouseID.add(objWarehouseID.toString());
            }
          }
        }
      } else if (strBillType == nc.vo.scm.pu.BillTypeConst.STORE_PO) { // 采购入库单
        for (int i = 0; i < billVO.getChildrenVO().length; i++) {
          if (billVO.getChildrenVO()[i] != null && billVO.getParentVO() != null) {
            objInvBaseID = billVO.getParentVO().getAttributeValue("cinvbasid");
            objWarehouseID = billVO.getChildrenVO()[i].getAttributeValue("cwarehouseid");
            if (PuPubVO.getString_TrimZeroLenAsNull(objInvBaseID) != null
                && PuPubVO.getString_TrimZeroLenAsNull(objWarehouseID) != null) {
              vctBaseID.add(objInvBaseID.toString());
              vctWarehouseID.add(objWarehouseID.toString());
            }
          }
        }
      }

      if (vctBaseID == null
          || vctWarehouseID == null
          || vctBaseID.size() < 1
          || vctWarehouseID.size() < 1
          || vctBaseID.size() != vctWarehouseID.size()) {
        return;
      }
      String[] arrInvBaseID = new String[vctBaseID.size()];
      String[] arrWarehouseID = new String[vctWarehouseID.size()];
      vctBaseID.copyInto(arrInvBaseID);
      vctWarehouseID.copyInto(arrWarehouseID);

      Object[][] oaRetWarehouseID = null; // 是否资产仓
      Object[][] oaRetInvBaseID = null; // 是否固定资产类存货

      oaRetWarehouseID =
          queryArrayValue(
              "bd_stordoc", "pk_stordoc", new String[] {"iscapitalstor"}, arrWarehouseID, null);
      oaRetInvBaseID =
          queryArrayValue(
              "bd_invbasdoc",
              "pk_invbasdoc",
              new String[] {"pk_assetscategory", "laborflag", "discountflag"},
              arrInvBaseID,
              null); // pk_assetscategory:固定资产类别ID
      // discountflag:价格折扣
      // laborflag:应税劳务

      if (oaRetWarehouseID == null
          || oaRetInvBaseID == null
          || oaRetWarehouseID.length < 1
          || oaRetInvBaseID.length < 1) {
        return;
      } else {
        for (int i = 0; i < oaRetWarehouseID.length; i++) {
          UFBoolean bRet = new UFBoolean((String) oaRetWarehouseID[i][0]);
          UFBoolean bRet2 = new UFBoolean((String) oaRetInvBaseID[i][0]);
          if ("Y".equalsIgnoreCase(oaRetInvBaseID[i][1].toString())
              && "n".equalsIgnoreCase(oaRetInvBaseID[i][2].toString())) // 应税劳务和价格折扣属性的存货不检查
          if (PuPubVO.getString_TrimZeroLenAsNull(bRet2) != null
                && !bRet.booleanValue()) { // 非固定资产存货(pk_assetscategory不为空)一定不能入资产仓
              throw new BusinessException("固定资产类存货只能对应固定资产仓");
            }
        }
      }
    } catch (Exception e) {
      // 日志异常
      nc.vo.scm.pub.SCMEnv.out(e);
      // 按规范抛出异常
      throw new BusinessException(e);
    }
  }
  /**
   * 此处插入方法说明。 功能描述: 自动将部门的条件变成包含所有下级部门 逻辑: 满足条件: 1- ConditionVO中包含 "部门"或“部门档案”项,而且存在PK值 返回值: 处理后的VO
   * 异常处理: 日期: 2003-09-05 谢高兴 输入参数:
   *
   * @param condvo nc.vo.pub.query.ConditionVO[]
   * @param String[] saPk_corp 需查的所有公司 处理逻辑: 1.先返回所有需要处理的项 2.然后将每个项生成相应的需要替换的VO列表 3.最后替换原来对应的项
   *     <p>修改时间:2007-8-21 修改人:张成 修改内容:增加对销售组织树型结构的支持-自动将销售组织的条件变成包含所有下级销售组织
   */
  public nc.vo.pub.query.ConditionVO[] getTotalSubPkVO(
      nc.vo.pub.query.ConditionVO[] condvo, String[] saPk_corp) throws Exception {
    int lenold;
    int lennew;

    lenold = condvo.length;
    if (lenold <= 0) {
      return condvo;
    }

    // 是否有部门项
    String sCurPk = null;
    boolean flag = false;
    ArrayList rowdept = new ArrayList();
    Integer newint;
    for (int i = 0; i < lenold; i++) {
      if ((condvo[i].getFieldName() != null)
          && (condvo[i].getFieldName().equals("部门")
              || condvo[i].getFieldName().equals("部门档案")
              || condvo[i].getFieldName().equals("销售组织") // v5.02增加
              // by
              // zhangcheng
              || condvo[i].getFieldName().indexOf("地区分类") >= 0 // v5.02增加
          // by
          // zhangcheng
          )
          && (("=".equals(condvo[i].getOperaCode()))
              || ("like".equals(condvo[i].getOperaCode()))
              || ("LIKE".equals(condvo[i].getOperaCode())))) {
        sCurPk = condvo[i].getValue();
        if (sCurPk != null && sCurPk.length() > 0) {
          newint = new Integer(i);
          rowdept.add(newint);
          flag = true;
        }
      }
    }

    if (!flag) {
      return condvo;
    }

    String[] sRetPk;
    // 包含所有子项的List
    ArrayList arAll = new ArrayList();
    for (int j = 0; j < rowdept.size(); j++) {
      // 单个项的List
      ArrayList arPer = new ArrayList();
      // 取下级部门的ID
      int rowindex = ((Integer) rowdept.get(j)).intValue();
      // sCurPk = condvo[rowindex].getValue();
      // 加入判断 避免空指针异常
      if (null != condvo[rowindex].getRefResult())
        sCurPk = condvo[rowindex].getRefResult().getRefPK();
      else sCurPk = NCLangResOnserver.getInstance().getStrByID("scmpub", "UPPscmpub-000054") /*
					 * @res
					 * "无效的输入!"
					 */;

      String sCurName;
      if (condvo[rowindex].getRefResult() != null) // 加入判断,避免抛错 wj
      sCurName = condvo[rowindex].getRefResult().getRefName();
      else sCurName = NCLangResOnserver.getInstance().getStrByID("scmpub", "UPPscmpub-000054") /*
																									 * @res
																									 * "无效的输入!"
																									 */;
      String sRetName[] = null; // modify by zxj

      // v5.02修改,增加对销售组织条件的处理////////////////////
      try {
        ArrayList retArray = null;
        if (("部门档案".equals(condvo[rowindex].getFieldName()))
            || ("部门".equals(condvo[rowindex].getFieldName()))) {
          retArray = getTotalSubPkAndNames(DEPTDOC, sCurPk, sCurName, saPk_corp);
        } else if (("销售组织".equals(condvo[rowindex].getFieldName()))) {
          retArray = getTotalSubPkAndNames(SALESTRU, sCurPk, sCurName, saPk_corp);
        } else if (null != condvo[rowindex].getFieldName()
            && condvo[rowindex].getFieldName().indexOf("地区分类") >= 0) {
          retArray = getTotalSubPkAndNames(AREACL, sCurPk, sCurName, saPk_corp);
        }
        sRetPk = (String[]) retArray.get(0);
        sRetName = (String[]) retArray.get(1);
      } catch (Exception e) {
        nc.vo.scm.pub.SCMEnv.out(e);
        /** <needn't ??> */
        sRetPk = null;
      }
      // v5.02修改////////////////////////////////////////

      // 如果只有原来一个值,则不进行替换
      if (sRetPk == null || sRetPk.length <= 1) {
        arAll.add(null);
        continue;
      }
      nc.vo.pub.query.ConditionVO vo;
      for (int i = 0; i < sRetPk.length; i++) {
        vo = new nc.vo.pub.query.ConditionVO();
        vo.setDataType(condvo[rowindex].getDataType());
        vo.setDirty(condvo[rowindex].isDirty());
        vo.setFieldCode(condvo[rowindex].getFieldCode());
        vo.setFieldName(condvo[rowindex].getFieldName());
        vo.setOperaCode(condvo[rowindex].getOperaCode());
        vo.setOperaName(condvo[rowindex].getOperaName());
        vo.setTableCode(condvo[rowindex].getTableCodeForMultiTable());
        vo.setTableName(condvo[rowindex].getTableNameForMultiTable());
        vo.setValue(sRetPk[i]);
        // modify by zxj
        nc.vo.pub.query.RefResultVO refresultvo = new nc.vo.pub.query.RefResultVO();
        refresultvo.setRefPK(sRetPk[i]);
        refresultvo.setRefName(sRetName[i]);
        vo.setRefResult(refresultvo);
        //

        // 关系操作设置位or
        vo.setLogic(false);
        // 第一个设置左括号,最后一个设置右括号
        if (i == 0) {
          vo.setNoLeft(false);
          // 如果原来有左括号,则设置为and
          if (!condvo[rowindex].getNoLeft()) {
            vo.setLogic(true);
          } else {
            vo.setLogic(condvo[rowindex].getLogic());
          }
        } else if (i == sRetPk.length - 1) {
          vo.setNoRight(false);
        }
        arPer.add(vo);
      }
      // 如果原来有左括号
      if (!condvo[rowindex].getNoLeft()) {
        vo = new nc.vo.pub.query.ConditionVO();
        // vo.setDataType(condvo[rowindex].getDataType());
        // 都设置为整数,最后的条件合成为1=1 如果是字符串合成是1='1'可能在其他的数据库中为非法
        vo.setDataType(1);
        vo.setFieldCode("1");
        vo.setOperaCode("=");
        vo.setValue("1");
        vo.setLogic(condvo[rowindex].getLogic());
        vo.setNoLeft(false);
        arPer.add(0, vo);
      }
      // 如果原来有右括号
      if (!condvo[rowindex].getNoRight()) {
        vo = new nc.vo.pub.query.ConditionVO();
        // vo.setDataType(condvo[rowindex].getDataType());
        vo.setDataType(1);
        vo.setFieldCode("1");
        vo.setOperaCode("=");
        vo.setValue("1");
        vo.setLogic(true);
        vo.setNoRight(false);
        arPer.add(vo);
      }

      arAll.add(arPer);
    }

    // 合成最后的List
    ArrayList arRes = new ArrayList();

    // 先复制原来的数组到list
    for (int i = 0; i < lenold; i++) {
      arRes.add(condvo[i]);
    }
    // 从后往前复制
    for (int j = rowdept.size() - 1; j >= 0; j--) {
      int rowindex = ((Integer) rowdept.get(j)).intValue();
      ArrayList arPer = (ArrayList) arAll.get(j);
      if (arPer == null) {
        continue;
      }
      arRes.remove(rowindex);
      if (rowindex >= arRes.size()) {
        // 从最后顺序增加
        for (int k = 0; k < arPer.size(); k++) {
          arRes.add(arPer.get(k));
        }
      } else {
        // 反着从中间插入
        for (int k = arPer.size() - 1; k >= 0; k--) {
          arRes.add(rowindex, arPer.get(k));
        }
      }
    }

    int iSize = arRes.size();
    return (nc.vo.pub.query.ConditionVO[]) (arRes.toArray(new nc.vo.pub.query.ConditionVO[iSize]));
  }
  /**
   * 作者:王印芬 功能:根据表、查询字段、查询条件得到符合条件的结果。 参数: String sTable 表,SQL中FROM后的字符 不能为空或空串 String sIdName
   * 主键字段名,如"corderid" 不能为空或空串 String[] saFields 需查询的所有域 不能为空,元素不能为空或空串 String[] saId 需查询的所有ID数组
   * 不能为空,元素不能为空或空串 String sWhere 除主键外的其他条件 可以为空 返回:Object[][] 可能为空或与saId长度相等。结构如下: 如fields[] =
   * {"d1","d2","d3"},则=(56,"dge",2002-03-12) 结果为空表示未有结果存在;元素为空表明该ID对应的值不存在。
   * 不返回所有元素均为空但返回结果不为空,或结果长度为<1的情况。 例外:SQLException SQL异常 日期:(2002-04-22 11:39:21)
   * 修改日期,修改人,修改原因,注释标志:
   */
  public Object[][] queryArrayValue(
      String sTable, String sIdName, String[] saFields, String[] saId, String sWhere)
      throws Exception {

    // 构造SQL语句
    StringBuffer sbufSql = new StringBuffer("select ");
    sbufSql.append(sIdName);
    sbufSql.append(",");
    sbufSql.append(saFields[0]);
    int iLen = saFields.length;
    for (int i = 1; i < iLen; i++) {
      sbufSql.append(",");
      sbufSql.append(saFields[i]);
    }
    sbufSql.append(" from ");
    sbufSql.append(sTable);
    sbufSql.append(" where ");
    sbufSql.append(sIdName + " in ");
    String strIdSet = "";
    try {
      nc.bs.scm.pub.TempTableDMO dmoTmpTbl = new nc.bs.scm.pub.TempTableDMO();
      strIdSet =
          dmoTmpTbl.insertTempTable(
              saId,
              nc.vo.scm.pub.TempTableVO.TEMPTABLE_PU14,
              nc.vo.scm.pub.TempTableVO.TEMPPKFIELD_PU);
      if (strIdSet == null || strIdSet.trim().length() == 0) strIdSet = "('TempTableDMOError')";
    } catch (Exception e) {
      nc.vo.scm.pub.SCMEnv.out(e);
      throw e;
    }
    sbufSql.append(strIdSet + " ");

    if (sWhere != null && sWhere.trim().length() > 1) {
      sbufSql.append("and ");
      sbufSql.append(sWhere);
    }

    Hashtable hashRet = new Hashtable();
    Vector vec = new Vector();
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
      con = getConnection();
      stmt = con.createStatement();
      rs = stmt.executeQuery(sbufSql.toString());
      //
      while (rs.next()) {
        String sId = rs.getString(1);
        Object[] ob = new Object[saFields.length];
        for (int i = 1; i < saFields.length + 1; i++) {
          ob[i - 1] = rs.getObject(i + 1);
        }
        hashRet.put(sId, ob);
      }
    } finally {
      // 关闭结果集,即时释放资源
      try {
        if (rs != null) rs.close();
      } catch (Exception e) {
      }
      try {
        if (stmt != null) stmt.close();
      } catch (Exception e) {
      }
      try {
        if (con != null) con.close();
      } catch (Exception e) {
      }
    }

    Object[][] oRet = null;
    if (hashRet.size() > 0) {
      iLen = saId.length;
      oRet = new Object[iLen][saFields.length];
      for (int i = 0; i < iLen; i++) {
        oRet[i] = (Object[]) hashRet.get(saId[i]);
      }
    }

    return oRet;
  }
  /**
   * 更新新增节点显示位置dispcode 孔晓东
   *
   * @param nodeCode新增模块根节点号
   * @param pos新增节点最后两位位置编码
   * @throws Exception
   */
  public void updateNodeDispCode(String nodeCode, String pos) throws Exception {

    int nodeLen = nodeCode.length();
    String superDispCode = null;
    String subDispCode = null;
    String superCode = nodeCode.substring(0, nodeLen - 2);
    String funid = null;
    String sqlfunid = "select cfunid from sm_funcregister where fun_code = '" + nodeCode + "'";
    String sqlDisp = "select disp_code from sm_funcregister where fun_code =?";
    String dispCode = null;
    Connection con = null;
    PreparedStatement stmt = null;
    ArrayList<String> subCodeList = new ArrayList<String>();

    try {
      con = getConnection();
      stmt = con.prepareStatement(sqlfunid.toString());
      ResultSet result = stmt.executeQuery();

      if (result.next()) {
        funid = result.getString("cfunid");
        String sqlSubcode =
            "select fun_code from sm_funcregister where parent_id = '"
                + funid
                + "' order by fun_code asc";
        stmt = con.prepareStatement(sqlSubcode.toString());
        result = stmt.executeQuery();
        while (result.next()) {
          subCodeList.add(result.getString("fun_code"));
        }
      }

      if (nodeLen > 2) {
        stmt = con.prepareStatement(sqlDisp.toString());
        stmt.setString(1, superCode);
        result = stmt.executeQuery();
        if (result.next()) {
          dispCode = result.getString("disp_code");
          superDispCode = dispCode;
        }
        stmt.setString(1, nodeCode);
        result = stmt.executeQuery();
        if (result.next()) {
          subDispCode = result.getString("disp_code");
        }
        boolean isrePeated = false;
        if (rootCode == null) {
          String doubleDispcodeCheckSql =
              "select disp_code from sm_funcregister where disp_code='" + subDispCode + "'";
          stmt = con.prepareStatement(doubleDispcodeCheckSql);
          result = stmt.executeQuery();
          int i = 0;
          while (result.next()) {
            i++;
          }

          if (i > 1) {
            isrePeated = true;
          }
          rootCode = nodeCode;
        }

        if ((dispCode != null
                && subDispCode != null
                && !subDispCode.substring(0, subDispCode.length() - 2).equals(superDispCode))
            || isrePeated) {

          dispCode = dispCode + pos;

          for (int i = 0; i < 20; i++) {
            String isUsedSql =
                "select fun_code from sm_funcregister where disp_code = '" + dispCode + "'";
            stmt = con.prepareStatement(isUsedSql);
            result = stmt.executeQuery();
            if (result.next()) {
              dispCode = getIncreaseCode(dispCode);
            } else {
              break;
            }
          }
          String sqlUpdate =
              "update sm_funcregister set disp_code='"
                  + dispCode
                  + "' where fun_code='"
                  + nodeCode
                  + "'";
          stmt = con.prepareStatement(sqlUpdate.toString());
          stmt.executeUpdate();
        }
      }

    } finally {
      try {
        if (stmt != null) {
          stmt.close();
        }
      } catch (Exception e) {
      }
      try {
        if (con != null) {
          con.close();
        }
      } catch (Exception e) {
        SCMEnv.error(e);
        throw new Exception(e);
      }
    }
    int index = 50;
    if (indexMap.get(subDispCode) != null) {
      index = indexMap.get(subDispCode).intValue();
    }
    for (String nodecode : subCodeList) {
      String indexString = String.valueOf(index);
      if (indexString.length() > 2) {
        indexString = String.valueOf(50 + new Random().nextInt(50));

      } else if (indexString.length() == 1) {
        indexString = "0" + indexString;
      }
      updateNodeDispCode(nodecode, indexString);

      index += 2;
      indexMap.put(superCode, new Integer(index));
    }
    rootCode = null;
  }