package nc.pubimpl.to.m5m.pub.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.data.IRowSet;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.PubAppTool;
import nc.vo.scmpub.res.billtype.ENTBillType;
import nc.vo.scmpub.res.billtype.ETBillType;
import nc.vo.scmpub.res.billtype.ICBillType;
import nc.vo.scmpub.res.billtype.SOBillType;
import nc.vo.scmpub.res.billtype.TOBillType;
import nc.vo.to.businessinfo.entity.BusinessinfoBBVO;
import nc.vo.to.businessinfo.entity.BusinessinfoBVO;
import nc.vo.to.businessinfo.entity.BusinessinfoHVO;
import nc.vo.to.businessinfo.entity.BusinessinfoVO;
import nc.vo.to.businessinfo.pub.QueryBusinessinfoVO;
import nc.vo.to.m5m.entity.PreSettleOutHeaderVO;
import nc.vo.to.m5m.entity.PreSettleOutItemVO;
import nc.vo.to.m5m.entity.PreSettleOutLineVO;
import nc.vo.to.m5m.entity.PreSettleOutVO;

import nc.impl.pubapp.pattern.database.DataAccessUtils;
import nc.pubitf.to.businessinfo.to.m5m.IBusinessinfoQueryService;

import nc.bs.framework.common.NCLocator;
import nc.bs.ml.NCLangResOnserver;

import nc.pubimpl.to.m5m.pub.rule.insert.DealTailDiffMny;

public class FillDataWithBusinessInfo {

  /**
   * 内部交易信息子子表字段
   */
  private final String[] busiInfoBBodyFields = new String[] {
    BusinessinfoBBVO.CUPFINANCEORGID, BusinessinfoBBVO.CUPFINANCEORGVID,
    BusinessinfoBBVO.CUPCOSTREGIONID, BusinessinfoBBVO.CDOWNFINANCEORGID,
    BusinessinfoBBVO.CDOWNFINANCEORGVID, BusinessinfoBBVO.CDOWNCOSTREGIONID,
    BusinessinfoBBVO.CORIGCURRENCYID, BusinessinfoBBVO.CPATHROWNO,
    BusinessinfoBBVO.NDISCOUNTRATE, BusinessinfoBBVO.NORIGTAXPRICE,
    BusinessinfoBBVO.NORIGPRICE, BusinessinfoBBVO.NQTORIGTAXMNY,
    BusinessinfoBBVO.NQTORIGMNY, BusinessinfoBBVO.FTAXTYPEFLAG,
    PreSettleOutLineVO.FTAXTYPEFLAG, BusinessinfoBBVO.NTAXRATE,
    BusinessinfoBBVO.NTAXRATE, BusinessinfoBBVO.NQTORIGPRICE,
    BusinessinfoBBVO.NQTORIGTAXPRICE, BusinessinfoBBVO.CINCOUNTRYID,
    BusinessinfoBBVO.COUTCOUNTRYID, BusinessinfoBBVO.CTAXCOUNTRYID,
    BusinessinfoBBVO.CINTAXCOUNTRYID, BusinessinfoBBVO.FBUYSELLFLAG,
    BusinessinfoBBVO.BTRIATRADEFLAG, BusinessinfoBBVO.CTAXCODEID,
    BusinessinfoBBVO.NCALTAXMNY, BusinessinfoBBVO.NTAX,
    BusinessinfoBBVO.NTAXMNY, BusinessinfoBBVO.NMNY,
    BusinessinfoBBVO.NTAXPRICE, BusinessinfoBBVO.NPRICE,
    BusinessinfoBBVO.NQTPRICE, BusinessinfoBBVO.NQTTAXPRICE,
    BusinessinfoBBVO.NEXCHANGERATE, BusinessinfoBBVO.CCURRENCYID
  };

  /**
   * 内部交易信息表体字段
   */
  private final String[] busiInfoBodyFields = new String[] {
    BusinessinfoBVO.CSETTLERULEID, BusinessinfoBVO.CSETTLERULE_BID,
    BusinessinfoBVO.NORIGPRICE, BusinessinfoBVO.NORIGTAXPRICE,
    BusinessinfoBVO.NBASEPRICE, BusinessinfoBVO.NBASETAXPRICE,
    BusinessinfoBVO.NBASEMNY, BusinessinfoBVO.NBASETAXMNY,
    BusinessinfoBVO.NBASETAXRATE, BusinessinfoBVO.VQTUNITRATE,
    BusinessinfoBVO.CQTUNITID, BusinessinfoBVO.NQTNUM,
    BusinessinfoBVO.BLARGESSFLAG, BusinessinfoBVO.FBASETAXTYPEFLAG,
    BusinessinfoBVO.NTAX, BusinessinfoBVO.CTAXCODEID,
    BusinessinfoBVO.NCALTAXMNY, BusinessinfoBVO.NPRICE,
    BusinessinfoBVO.NTAXPRICE, BusinessinfoBVO.NQTPRICE,
    BusinessinfoBVO.NQTTAXPRICE, BusinessinfoBVO.NMNY, BusinessinfoBVO.NTAXMNY
  };

  /**
   * 内部交易信息表头字段
   */
  private final String[] busiInfoHeadFields = new String[] {
    BusinessinfoHVO.FSETTLETYPEFLAG, BusinessinfoHVO.BREVERSEFLAG,
    BusinessinfoHVO.BUNILATERALFLAG, BusinessinfoHVO.CSETTLEPATHID,
    BusinessinfoHVO.BBASEDISCOUNTFLAG, BusinessinfoHVO.CCURRENCYID,
    BusinessinfoHVO.FONWAYOWNERFLAG, BusinessinfoHVO.CINCOUNTRYID,
    BusinessinfoHVO.COUTCOUNTRYID, BusinessinfoHVO.CTAXCOUNTRYID,
    BusinessinfoHVO.CINTAXCOUNTRYID, BusinessinfoHVO.FBUYSELLFLAG,
    BusinessinfoHVO.BTRIATRADEFLAG, BusinessinfoHVO.CTRADEWORDID,
    BusinessinfoHVO.NEXCHANGERATE, BusinessinfoHVO.CBASECURRENCYID
  };

  private Map<String, BusinessinfoVO> mapBusiInfo;

  private List<PreSettleOutVO> nobusinessList = new ArrayList<PreSettleOutVO>();

  /**
   * 待结算调出单子子表字段
   */
  private final String[] psoBBodyFields = new String[] {
    PreSettleOutLineVO.CUPFINANCEORGID, PreSettleOutLineVO.CUPFINANCEORGVID,
    PreSettleOutLineVO.CUPCOSTREGIONID, PreSettleOutLineVO.CDOWNFINANCEORGID,
    PreSettleOutLineVO.CDOWNFINANCEORGVID,
    PreSettleOutLineVO.CDOWNCOSTREGIONID, PreSettleOutLineVO.CCURRENCYID,
    PreSettleOutLineVO.CROWNO, PreSettleOutLineVO.NDISCOUNTRATE,
    PreSettleOutLineVO.NORIGTAXPRICE, PreSettleOutLineVO.NORIGPRICE,
    PreSettleOutLineVO.NORIGTAXMNY, PreSettleOutLineVO.NORIGMNY,
    PreSettleOutLineVO.FTAXTYPEFLAG, PreSettleOutLineVO.FARTAXTYPEFLAG,
    PreSettleOutLineVO.NTAXRATE, PreSettleOutLineVO.NARTAXRATE,
    PreSettleOutLineVO.NORIGQTPRICE, PreSettleOutLineVO.NORIGQTTAXPRICE,
    PreSettleOutLineVO.CINCOUNTRYID, PreSettleOutLineVO.COUTCOUNTRYID,
    PreSettleOutLineVO.COUTTAXCOUNTRYID, PreSettleOutLineVO.CINTAXCOUNTRYID,
    PreSettleOutLineVO.FOUTBUYSELLFLAG, PreSettleOutLineVO.BOUTTRIATRADEFLAG,
    PreSettleOutLineVO.CTAXCODEID, PreSettleOutLineVO.NCALTAXMNY,
    PreSettleOutLineVO.NTAX, PreSettleOutLineVO.NTAXMNY,
    PreSettleOutLineVO.NMNY, PreSettleOutLineVO.NTAXPRICE,
    PreSettleOutLineVO.NPRICE, PreSettleOutLineVO.NQTPRICE,
    PreSettleOutLineVO.NQTTAXPRICE, PreSettleOutLineVO.NEXCHANGERATE,
    PreSettleOutLineVO.COUTCURRENCYID
  };

  /**
   * 待结算调出单表体字段
   */
  private final String[] psoBodyFields = new String[] {
    PreSettleOutItemVO.CSETTLERULEID, PreSettleOutItemVO.CSETTLERULE_BID,
    PreSettleOutItemVO.NORIGPRICE, PreSettleOutItemVO.NORIGTAXPRICE,
    PreSettleOutItemVO.NQTORIGPRICE, PreSettleOutItemVO.NQTORIGTAXPRICE,
    PreSettleOutItemVO.NORIGMNY, PreSettleOutItemVO.NORIGTAXMNY,
    PreSettleOutItemVO.NTAXRATE, PreSettleOutItemVO.VQTUNITRATE,
    PreSettleOutItemVO.CQTUNITID, PreSettleOutItemVO.NQTNUM,
    PreSettleOutItemVO.BLARGESSFLAG, PreSettleOutItemVO.FTAXTYPEFLAG,
    PreSettleOutItemVO.NTAX, PreSettleOutItemVO.CTAXCODEID,
    PreSettleOutItemVO.NCALTAXMNY, PreSettleOutItemVO.NPRICE,
    PreSettleOutItemVO.NTAXPRICE, PreSettleOutItemVO.NQTPRICE,
    PreSettleOutItemVO.NQTTAXPRICE, PreSettleOutItemVO.NMNY,
    PreSettleOutItemVO.NTAXMNY
  };

  /**
   * 待结算调出单需要从内部交易信息表头获取值的表头字段
   */
  private final String[] psoHeadFields = new String[] {
    PreSettleOutHeaderVO.FSETTLETYPEFLAG, PreSettleOutHeaderVO.BREVERSEFLAG,
    PreSettleOutHeaderVO.BUNILATERALFLAG, PreSettleOutHeaderVO.CSETTLEPATHID,
    PreSettleOutHeaderVO.BBASEDISCOUNTFLAG,
    PreSettleOutHeaderVO.CORIGCURRENCYID, PreSettleOutHeaderVO.FONWAYOWNERFLAG,
    PreSettleOutHeaderVO.CINCOUNTRYID, PreSettleOutHeaderVO.COUTCOUNTRYID,
    PreSettleOutHeaderVO.COUTTAXCOUNTRYID,
    PreSettleOutHeaderVO.CINTAXCOUNTRYID, PreSettleOutHeaderVO.FOUTBUYSELLFLAG,
    PreSettleOutHeaderVO.BOUTTRIATRADEFLAG, PreSettleOutHeaderVO.CTRADEWORDID,
    PreSettleOutHeaderVO.NEXCHANGERATE, PreSettleOutHeaderVO.CCURRENCYID
  };

  public void fillDataByBusinessInfo(PreSettleOutVO[] vos) {
    this.init(vos);
    List<PreSettleOutVO> businessList = new ArrayList<PreSettleOutVO>();
    for (PreSettleOutVO vo : vos) {
      PreSettleOutHeaderVO header = vo.getHeaderVO();
      PreSettleOutItemVO[] items = vo.getItemVOs();
      Map<String, BusinessinfoBVO> mapBusiInfoBody =
          new HashMap<String, BusinessinfoBVO>();
      BusinessinfoVO info =
          this.mapBusiInfo.get(this.getMapBusiInfoKey(header, items[0]));
      // 发货单修改发货库存组织，由非跨组织销售修改成跨组织销售场景下 2013-6-27 jdm wangyfg
      if (SOBillType.Order.getCode().equals(items[0].getVfirsttype())
          && (null == info || null == info.getChildrenVO())) {
        this.nobusinessList.add(vo);
        continue;
      }
      // 发货单修改发货库存组织，和销售订单的发货库存组织不一致的场景下 2013-6-27 jdm wangyfg
      if (SOBillType.Order.getCode().equals(items[0].getVfirsttype())
          && (!header.getPk_org().equals(info.getParentVO().getPk_org()) || !header
              .getCinfinanceorgid().equals(
                  info.getParentVO().getCinfinanceorgid()))) {
        this.nobusinessList.add(vo);
        continue;
      }
      // 源头是出口合同的没有销售订单，没有内部交易信息 2014-04-30 yuxla chenxin wanglip
      if (ETBillType.CONTRACT.getCode().equals(items[0].getVfirsttype())) {
        this.nobusinessList.add(vo);
        continue;
      }
      // 源头是转口合同的没有销售订单，没有内部交易信息
      if (ENTBillType.CONTRACT.getCode().equals(items[0].getVfirsttype())) {
        this.nobusinessList.add(vo);
        continue;
      }
      for (PreSettleOutItemVO item : items) {
        String bid = item.getCsrcbid();
        BusinessinfoVO infovo =
            this.mapBusiInfo.get(this.getMapBusiInfoKey(header, item));

        if (null == infovo || null == infovo.getChildrenVO()
            && !SOBillType.Order.getCode().equals(item.getVfirsttype())) {
          String message =
              NCLangResOnserver.getInstance().getStrByID("4009003_0",
                  "04009003-0310")/*"没有对应的内部交易信息，请检查"*/;
          ExceptionUtils.wrappBusinessException(message);
        }

        if (!mapBusiInfoBody.containsKey(bid)) {
          BusinessinfoBVO[] infoItems = infovo.getChildrenVO();
          for (BusinessinfoBVO biItem : infoItems) {
            String srcbid = biItem.getCsrcbid();
            mapBusiInfoBody.put(srcbid, biItem);

          }
        }
        this.fillBusiInfoHeadInfo(header, infovo.getParentVO());
        this.fillBusiInfoBodyInfo(item, mapBusiInfoBody);
        this.fillBusiInfoBBodyInfo(header, item, infovo);

      }
      businessList.add(vo);
    }
    if (businessList.size() > 0) {
      this.fillInVat(vos);

      this.dealTailDiff(vos);
    }

  }

  public List<PreSettleOutVO> getNoBusinessList() {
    return this.nobusinessList;
  }

  private void buildLineVOWithBizInfo(PreSettleOutHeaderVO header,
      PreSettleOutItemVO item, BusinessinfoBBVO[] infobbvos) {

    // 路径长度
    int len = infobbvos.length;
    PreSettleOutLineVO[] linevos = new PreSettleOutLineVO[len];
    for (int i = 0; i < len; i++) {
      linevos[i] = new PreSettleOutLineVO();
      for (int j = 0; j < this.psoBBodyFields.length; j++) {
        if (this.psoBBodyFields[j]
            .equalsIgnoreCase(PreSettleOutLineVO.CUPCOSTREGIONID)) {
          String cupcostregion =
              (String) infobbvos[i]
                  .getAttributeValue(this.busiInfoBBodyFields[j]);
          String cupfiorgid =
              (String) infobbvos[i]
                  .getAttributeValue(PreSettleOutLineVO.CUPFINANCEORGID);
          String pk_org = header.getPk_org();
          if (null == cupcostregion && PubAppTool.isEqual(cupfiorgid, pk_org)) {
            linevos[i].setCupcostregionid(header.getCoutcostregionid());
          }
        }
        else if (this.psoBBodyFields[j]
            .equalsIgnoreCase(PreSettleOutLineVO.CDOWNCOSTREGIONID)) {
          String cdowncostregion =
              (String) infobbvos[i]
                  .getAttributeValue(this.busiInfoBBodyFields[j]);
          String cdownfiorgid =
              (String) infobbvos[i]
                  .getAttributeValue(PreSettleOutLineVO.CDOWNFINANCEORGID);
          String cinfiorgid = header.getCinfinanceorgid();
          if (null == cdowncostregion
              && PubAppTool.isEqual(cdownfiorgid, cinfiorgid)) {
            linevos[i].setCdowncostregionid(header.getCincostregionid());
          }
        }
        linevos[i].setAttributeValue(this.psoBBodyFields[j],
            infobbvos[i].getAttributeValue(this.busiInfoBBodyFields[j]));
      }

    }
    item.setLineVOs(linevos);

  }

  private void dealTailDiff(PreSettleOutVO[] vos) {
    List<PreSettleOutItemVO> deallist = new ArrayList<PreSettleOutItemVO>();
    Map<String, PreSettleOutHeaderVO> headMap =
        new HashMap<String, PreSettleOutHeaderVO>();
    for (PreSettleOutVO vo : vos) {
      PreSettleOutHeaderVO head = vo.getHeaderVO();
      PreSettleOutItemVO[] items = vo.getItemVOs();
      if (items[0] != null) {
        headMap.put(items[0].getCbillid(), head);
      }
      UFBoolean flag =
          head.getBmainthreadflag() == null ? UFBoolean.FALSE : head
              .getBmainthreadflag();
      for (PreSettleOutItemVO item : items) {
        if (!PubAppTool.isNull(item.getVfirsttype())
            && (item.getVfirsttype().equals(TOBillType.TransOrder.getCode())
                && flag.booleanValue() || item.getVfirsttype().equals(
                SOBillType.Order.getCode()))) {
          deallist.add(item);
        }
      }
    }

    if (deallist.size() == 0) {
      return;
    }

    DealTailDiffMny deal = new DealTailDiffMny();
    deal.deatTailDiffMny(deallist, headMap);

  }

  private void fillBusiInfoBBodyInfo(PreSettleOutHeaderVO header,
      PreSettleOutItemVO item, BusinessinfoVO infovo) {

    BusinessinfoBVO[] infoItems = infovo.getChildrenVO();
    Map<String, BusinessinfoBVO> map = new HashMap<String, BusinessinfoBVO>();
    for (BusinessinfoBVO biItem : infoItems) {
      String srcbid = biItem.getCsrcbid();
      map.put(srcbid, biItem);
    }
    String srcbid = item.getCsrcbid();
    BusinessinfoBVO infobvo = map.get(srcbid);
    BusinessinfoBBVO[] infobbvos = infobvo.getBBVO();
    if (null != infobbvos && infobbvos.length > 0) {
      // 多路径的待结算调出单子子表VO生成
      for (BusinessinfoBBVO bbvo : infobbvos) {
        bbvo.setNum(infobvo.getNnumber());

      }

      this.buildLineVOWithBizInfo(header, item, infobbvos);
    }
    else {
      // 内部交易信息子子表不能为空
      String msg =
          NCLangResOnserver.getInstance().getStrByID("4009003_0",
              "04009003-0276", null, new String[] {
                infobvo.getCbusinessid()
              })/*数据错误：内部交易信息子子表信息为空！请检查！\n内部交易信息ID：{0}*/;
      ExceptionUtils.wrappBusinessException(msg);
    }

  }

  private void fillBusiInfoBodyInfo(PreSettleOutItemVO item,
      Map<String, BusinessinfoBVO> mapBusiInfoBody) {

    String srcbid = item.getCsrcbid();
    BusinessinfoBVO infobvo = mapBusiInfoBody.get(srcbid);
    for (int i = 0; i < this.psoBodyFields.length; i++) {
      item.setAttributeValue(this.psoBodyFields[i],
          infobvo.getAttributeValue(this.busiInfoBodyFields[i]));
    }

  }

  private void fillBusiInfoHeadInfo(PreSettleOutHeaderVO header,
      BusinessinfoHVO parentVO) {
    for (int i = 0; i < this.psoHeadFields.length; i++) {
      String billtype = header.getVsrctype();
      if (!this.psoHeadFields[i].equals(PreSettleOutHeaderVO.CTRADEWORDID)
          || billtype.equals(ICBillType.TransIn.getCode())
          || billtype.equals(ICBillType.TransOut.getCode())) {
        if (this.psoHeadFields[i].equals(PreSettleOutHeaderVO.FONWAYOWNERFLAG)) {
          continue;
        }
        header.setAttributeValue(this.psoHeadFields[i],
            parentVO.getAttributeValue(this.busiInfoHeadFields[i]));

      }

    }

  }

  private void fillInVat(PreSettleOutVO[] vos) {
    List<PreSettleOutVO> list = new ArrayList<PreSettleOutVO>();
    for (PreSettleOutVO vo : vos) {
      PreSettleOutHeaderVO head = vo.getHeaderVO();
      UFBoolean flag =
          head.getBunilateralflag() == null ? UFBoolean.FALSE : head
              .getBunilateralflag();
      if (flag.booleanValue()) {
        continue;
      }
      list.add(vo);
    }
    if (list.size() == 0) {
      return;
    }

    this.fillItemVAT(list.toArray(new PreSettleOutVO[list.size()]));
    this.fillLineVAT(list.toArray(new PreSettleOutVO[list.size()]));

  }

  private void fillItemVAT(PreSettleOutVO[] vos) {

	DataAccessUtils utils = new DataAccessUtils();
    FillVATFieldUtil util = new FillVATFieldUtil();
    util.fillInVATField(vos);
    for (PreSettleOutVO vo : vos) {
      PreSettleOutItemVO[] items = vo.getItemVOs();
      for (PreSettleOutItemVO item : items) {
        if (item.getCtaxcodeid() != null
            && item.getCtaxcodeid().equals(item.getCintaxcodeid())) {
          item.setNintaxrate(item.getNtaxrate());
        }
        //出库单签字寻不到税率时从增值税税码税率里面获取----begin
        else{
        	String sql = "select bd_taxcode.pk_taxcode, bd_taxrate.taxrate, bd_taxrate.taxtype " +
        			"from bd_material bd_material inner join bd_taxcode bd_taxcode on bd_taxcode.mattaxes = bd_material.pk_mattaxes " +
        			"inner join bd_taxrate bd_taxrate on bd_taxrate.pk_taxcode = bd_taxcode.pk_taxcode " +
        			"where bd_material.pk_material='" + item.getCinventoryid() +"' and bd_material.dr=0";
        	IRowSet query = utils.query(sql);
        	while(query.next()){
        		item.setCintaxcodeid(query.getString(0));
        		item.setNintaxrate(new UFDouble(query.getString(1)));
        		item.setFintaxtypeflag(query.getInteger(2));
        		break;
        	}
        }
        //出库单签字寻不到税率时从增值税税码税率里面获取----end
      }
    }

  }

  private void fillLineVAT(PreSettleOutVO[] vos) {
    List<PreSettleOutVO> list = new ArrayList<PreSettleOutVO>();
    for (PreSettleOutVO vo : vos) {
      PreSettleOutHeaderVO head = vo.getHeaderVO();
      PreSettleOutItemVO[] items = vo.getItemVOs();
      String cpathid = head.getCsettlepathid();

      if (!PubAppTool.isNull(cpathid)) {
        for (PreSettleOutItemVO item : items) {
          PreSettleOutLineVO[] lines = item.getLineVOs();
          for (PreSettleOutLineVO line : lines) {
            line.setCinventoryid(item.getCinventoryid());
          }

        }

        list.add(vo);
        continue;
      }

      for (PreSettleOutItemVO item : items) {
        PreSettleOutLineVO[] lines = item.getLineVOs();
        lines[0].setBintriatradeflag(head.getBintriatradeflag());
        lines[0].setFinbuysellflag(head.getFinbuysellflag());
        lines[0].setCintaxcodeid(item.getCintaxcodeid());
        lines[0].setFintaxtypeflag(item.getFintaxtypeflag());
        lines[0].setNintaxrate(item.getNintaxrate());
        lines[0].setNnosubtaxrate(item.getNnosubtaxrate());
        lines[0].setBopptaxflag(item.getBopptaxflag());
      }
    }
    if (list.size() == 0) {
      return;
    }
    FillPathInVATFieldUtil pathfill = new FillPathInVATFieldUtil();
    pathfill.fillLineVATPath(list.toArray(new PreSettleOutVO[list.size()]));
  }

  private String getMapBusiInfoKey(PreSettleOutHeaderVO header,
      PreSettleOutItemVO item) {
    String billtype = header.getVsrctype();
    String coutfinanceid = header.getPk_org();
    String cinfinanceid = header.getCinfinanceorgid();
    String bid = item.getCsrcbid();
    StringBuffer sb = new StringBuffer();
    sb.append(bid);
    sb.append(coutfinanceid);
    sb.append(cinfinanceid);
    sb.append(billtype);
    return sb.toString();
  }

  private String getMapBusiInfoKey(QueryBusinessinfoVO queryVO) {
    String bid = queryVO.getBid();
    String coutfinanceid = queryVO.getCoutfinanceid();
    String cinfinanceid = queryVO.getCinfinanceid();
    String billtype = queryVO.getBilltype();
    StringBuffer sb = new StringBuffer();
    sb.append(bid);
    sb.append(coutfinanceid);
    sb.append(cinfinanceid);
    sb.append(billtype);
    return sb.toString();
  }

  private void init(PreSettleOutVO[] vos) {

    Set<QueryBusinessinfoVO> hsQueryVOs = new HashSet<QueryBusinessinfoVO>();
    for (PreSettleOutVO vo : vos) {
      // 来源单据类型
      String billtype = vo.getHeaderVO().getVsrctype();
      // 调出财务组织
      String coutfinanceid = vo.getHeaderVO().getPk_org();
      // 调入财务组织
      String cinfinanceid = vo.getHeaderVO().getCinfinanceorgid();
      PreSettleOutItemVO[] items = vo.getItemVOs();
      for (PreSettleOutItemVO item : items) {
        // 来源单据表体id
        String bid = item.getCsrcbid();
        QueryBusinessinfoVO queryVO = new QueryBusinessinfoVO();
        queryVO.setBid(bid);
        queryVO.setCoutfinanceid(coutfinanceid);
        queryVO.setCinfinanceid(cinfinanceid);
        queryVO.setBilltype(billtype);
        hsQueryVOs.add(queryVO);
      }
    }
    // 查询内部交易信息
    QueryBusinessinfoVO[] queryVOs = new QueryBusinessinfoVO[hsQueryVOs.size()];
    hsQueryVOs.toArray(queryVOs);
    IBusinessinfoQueryService service =
        NCLocator.getInstance().lookup(IBusinessinfoQueryService.class);
    try {
      service.query(queryVOs);
    }
    catch (Exception e) {
      ExceptionUtils.wrappException(e);
    }

    this.mapBusiInfo = new HashMap<String, BusinessinfoVO>();
    for (QueryBusinessinfoVO queryVO : queryVOs) {
      // 没查到内部交易信息则跳过
      if (null == queryVO.getBusinessinfoVO()) {
        continue;
      }
      this.mapBusiInfo.put(this.getMapBusiInfoKey(queryVO),
          queryVO.getBusinessinfoVO());
    }

  }

}
