NC6 UAP流程平台适配 类 nc.itf.scmpub.reference.uap.pf.PfServiceScmUtil

/**
 * $文件说明$
 *
 * @author zhaoyha
 * @version 6.0
 * @see
 * @since 6.0
 * @time 2010-1-29 上午11:14:39
 */
package nc.itf.scmpub.reference.uap.pf;

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

import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.pf.pub.PfDataCache;
import nc.bs.pub.pf.PfUtilTools;
import nc.itf.uap.pf.IPFBusiAction;
import nc.itf.uap.pf.IPFConfig;
import nc.itf.uap.pf.IPFMetaModel;
import nc.itf.uap.pf.IPFWorkflowQry;
import nc.itf.uap.pf.IPfExchangeService;
import nc.itf.uap.pf.busiflow.PfButtonClickContext;
import nc.itf.uap.pf.metadata.IFlowBizItf;
import nc.uap.pf.metadata.PfMetadataTools;
import nc.vo.jcom.lang.StringUtil;
import nc.vo.ml.MultiLangContext;
import nc.vo.pf.change.ExchangeVO;
import nc.vo.pf.change.PfUtilBaseTools;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.billtype.BilltypeVO;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.pfflow01.BillbusinessVO;
import nc.vo.pub.pfflow04.MessagedriveVO;
import nc.vo.pub.workflownote.WorkflownoteVO;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.IBill;
import nc.vo.pubapp.pattern.pub.MapList;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.util.remotecallcombination.RemoteCallCombinatorEx;
import nc.vo.util.remotecallcombination.Token;
import nc.vo.wfengine.definition.WorkflowTypeEnum;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

/**
 * <p>
 * <b>本类主要完成以下功能:</b>
 * <ul>
 * <li>UAP流程平台适配
 * </ul>
 * <p>
 * <p>
 * 
 * @version 6.0
 * @since 6.0
 * @author zhaoyha
 * @time 2010-1-29 上午11:14:39
 */
public class PfServiceScmUtil {

  /**
   * 方法功能描述:执行VO对照,先根据流程找目的交易类型,找不到再根据单据接口定义找
   * <p>
   * <b>参数说明</b>
   * 
   * @param <E> 源单据VO类型
   * @param <T> 目标单据VO类型
   * @param sourceType 上游单据类型(或交易类型)
   * @param desType 下游单据类型(或交易类型)
   * @param sourceVos 上游单据VO数组
   * @return 交换后的下游单据VO数组
   *         <p>
   * @since 6.0
   * @author zhaoyha
   * @time 2010-4-12 下午12:34:52
   */
  @SuppressWarnings("unchecked")
  public static <T extends AggregatedValueObject> T[] executeVOChange(
      String sourceType, String desType, AggregatedValueObject[] sourceVos) {
    try {
      return (T[]) PfUtilTools.runChangeDataAry(sourceType, desType, sourceVos);
    }
    catch (Exception e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 从接口关系找到目的交易类型,并走不同的VO交换,将目的交易类型放到目的VO中
   * 
   * @param sourceType 源单据类型(编码)
   * @param desType 目的单据类型(编码)
   * @param sourceVos 源单据聚合VO数组
   * @return 目的单据聚合VO数组
   */
  @SuppressWarnings("unchecked")
  public static <T extends AggregatedValueObject> T[] exeVOChangeByBillItfDef(
      String sourceType, String desType, AggregatedValueObject[] sourceVos) {
    if (null == sourceVos || sourceVos.length == 0) {
      return null;
    }
    try {
      return (T[]) NCLocator
          .getInstance()
          .lookup(IPfExchangeService.class)
          .runChangeDataAryNeedClassify(sourceType, desType, sourceVos, null,
              PfButtonClickContext.ClassifyByItfdef);
    }
    catch (BusinessException e) {
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 从接口流程中找目的交易类型,并走不同的VO交换,将目的交易类型放到目的VO中
   * 
   * @param sourceType 源单据类型(编码)
   * @param desType 目的单据类型(编码)
   * @param sourceVos 源单据聚合VO数组
   * @return 目的单据聚合VO数组
   */
  @SuppressWarnings("unchecked")
  public static <T extends AggregatedValueObject> T[] exeVOChangeByBizFlow(
      String sourceType, String desType, AggregatedValueObject[] sourceVos) {
    if (null == sourceVos || sourceVos.length == 0) {
      return null;
    }
    try {
      return (T[]) NCLocator
          .getInstance()
          .lookup(IPfExchangeService.class)
          .runChangeDataAryNeedClassify(sourceType, desType, sourceVos, null,
              PfButtonClickContext.ClassifyByBusiflow);
    }
    catch (BusinessException e) {
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 查询某业务流程下两个单据(或交易)类型之间是否存在动作驱动
   * 
   * @param busitype 业务流程
   * @param operator 当前操作员
   * @param srcBillorTransType 来源单据或交易类型
   * @param destBillorTransType 源头单据或交易类型
   * @return
   */
  public static UFBoolean existActionDrive(String busitype, String operator,
      String srcBillorTransType, String destBillorTransType) {
    try {
      return NCLocator
          .getInstance()
          .lookup(IPFConfig.class)
          .existActionDrive(busitype, operator, srcBillorTransType,
              destBillorTransType);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  public static BillbusinessVO[] findBillbusinessVOs(String biztype,
      String pkGroup) {
    try {
      return NCLocator.getInstance().lookup(IPFConfig.class)
          .findBillbusinessVOs(biztype, pkGroup);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 从数据库读取VO交换规则
   * 
   * @param srcBillOrTranstype
   * @param destBillOrTranstype
   * @param sourceBillVO
   * @param pk_group
   * @return
   */
  public static ExchangeVO findVOConversionFromDB(String srcBillOrTranstype,
      String destBillOrTranstype, AggregatedValueObject sourceBillVO,
      String pk_group) {
    try {
      // return PfBillMappingUtil.findVOConversionFromDB(srcBillOrTranstype,
      // destBillOrTranstype, sourceBillVO, pk_group);
      return NCLocator
          .getInstance()
          .lookup(IPfExchangeService.class)
          .findVOConversionFromDB(srcBillOrTranstype, destBillOrTranstype,
              sourceBillVO, pk_group);
    }
    catch (BusinessException e) {
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 得到审批流中指定单据的所有已经审批(已经处理过审批任务)过的用户
   * 
   * @param billids 已经进入审批流,并已经有人审批过的单据ID数组
   * @return MapList {单据id,审批完成的审批人列表},不为null
   */
  public static MapList<String, String> getApprovedUser(String[] billids) {
    MapList<String, String> ml = new MapList<String, String>();
    try {
      IPFWorkflowQry pfqry =
          NCLocator.getInstance().lookup(IPFWorkflowQry.class);
      // UAP未提供批量方法,只能循环
      for (String billId : billids) {
        WorkflownoteVO[] wfnVos =
            pfqry.queryWorkitems(billId, null,
                WorkflowTypeEnum.Approveflow.getIntValue(), 1);
        if (null == wfnVos) {
          continue;
        }
        for (WorkflownoteVO wfnVo : wfnVos) {
          ml.put(billId, wfnVo.getCheckman());
        }
      }
    }
    catch (Exception e) {
      ExceptionUtils.wrappException(e);
    }
    return ml;
  }

  /**
   * 方法功能描述:根据交易类型代码获得对应的单据类型代码
   * <p>
   * <b>参数说明</b>
   * 
   * @param transTypeCode
   * @return <p>
   * @since 6.0
   * @author hanbin
   * @time 2010-3-11 下午02:11:41
   */
  public static String getBillTypeByTransType(String transTypeCode) {
    return PfUtilBaseTools.getRealBilltype(transTypeCode);
  }

  /**
   * 方法功能描述:查询业务单据的业务接口实现类的实例
   * <p>
   * <b>参数说明</b>
   * 
   * @param <T>
   * @param billVo
   * @param clz
   * @return <p>
   * @since 6.0
   * @author hanbin
   * @time 2010-3-11 下午01:57:17
   */
  public static IFlowBizItf getBizItfImpl(IBill bill) {

    return PfMetadataTools.getBizItfImpl(bill, IFlowBizItf.class);
  }

  public static IFlowBizItf getBizItfImpl(Object object) {
    return PfMetadataTools.getBizItfImpl(object, IFlowBizItf.class);
  }

  /**
   * 方法功能描述:获取流程id
   * <p>
   * <b>参数说明</b>
   * 
   * @param billtype
   * @param transtype
   * @param pk_org
   * @param userid
   * @return <p>
   * @since 6.0
   * @author yangb
   * @time 2010-9-12 上午12:14:26
   */
  public static String getBusitype(String billtype, String transtype,
      String pk_org, String userid) {
    try {
      IPFConfig conf = NCLocator.getInstance().lookup(IPFConfig.class);
      return conf.retBusitypeCanStart(billtype, transtype, pk_org, userid);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 根据合并调用信息,取得业务流程
   * 
   * @param billtype
   * @param transtype
   * @param pk_org
   * @param userid
   * @param t
   * @return
   */
  public static String getBusitype(String billtype, String transtype,
      String pk_org, String userid, Token t) {
    if (null == t) {
      return PfServiceScmUtil.getBusitype(billtype, transtype, pk_org, userid);
    }
    try {
      return (String) RemoteCallCombinatorEx.getInstance().getResult(t);
    }
    catch (BusinessException e) {
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 返回指定业务流程中,存在指定的单据类型(也可其交易类型)参照另外一个指定的单据类型(也可其交易类型)的业务流程。 <br>
   * 
   * @param billtype
   * @param refbilltype
   * @param pk_busitypes
   * @return sql片断 select pk_businesstype from pub_billsource ...
   */
  public static String getQueryBillRefBillSql(String billtype,
      String refbilltype, String[] pk_busitypes) {
    SqlBuilder sql = new SqlBuilder();
    sql.append("select  pk_businesstype from pub_billsource");
    sql.append(" where pk_businesstype", pk_busitypes);
    sql.append(" and referbilltype like '" + refbilltype + "%'");
    sql.append(" and pk_billtype like '" + billtype + "%'");
    return sql.toString();
  }

  /**
   * 方法功能描述:根据交易类型代码获得对应的交易类型名称
   * <p>
   * <b>参数说明</b>
   * 
   * @param transTypeCode
   * @return <p>
   * @since 6.0
   * @author songhy
   * @time 2010-4-28 下午02:12:57
   */
  public static String getTransTypeNameByCode(String transTypeCode) {
    BilltypeVO billtype = PfDataCache.getBillType(transTypeCode);
    if (null == billtype) {
      return null;
    }
    Integer seq = MultiLangContext.getInstance().getCurrentLangSeq();
    if (seq == null || seq == -1 || seq == 1) {
      return billtype.getBilltypename();
    }
    return (String) billtype.getAttributeValue("billtypename"
        + String.valueOf(seq));
  }
  

  /**
   * 根据交易类型id,返回当前集团内的交易类型代码
   * 
   * @param trantypeid
   * @return
   */
  public static String getTrantypecodeByid(String trantypeid) {
    return PfServiceScmUtil.getTrantypecodeByids(new String[] {
      trantypeid
    }).get(trantypeid);
  }

  /**
   * 根据交易类型ids,返回当前集团内的交易类型代码
   * 
   * @param trantypeids
   * @return
   */
  public static Map<String, String> getTrantypecodeByids(String[] trantypeids) {
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    List<BilltypeVO> typeAndTrantypeList =
        PfDataCache.getBillTypeAndTranstypesInGrp(pk_group);
    if (CollectionUtils.isEmpty(typeAndTrantypeList)) {
      return null;
    }
    Set<String> ttSet = new HashSet<String>(Arrays.asList(trantypeids));
    Map<String, String> map = new HashMap<String, String>();
    for (BilltypeVO vo : typeAndTrantypeList) {
      if (ttSet.contains(vo.getPk_billtypeid())) {
        map.put(vo.getPk_billtypeid(), vo.getPk_billtypecode());
      }
    }
    return map;
  }

  /**
   * 根据当前集团内的交易类型code,返回交易类型id
   * 
   * @param trantypeids
   * @return
   */
  public static Map<String, String> getTrantypeidByCode(String[] trantypecode) {
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    List<BilltypeVO> typeAndTrantypeList =
        PfDataCache.getBillTypeAndTranstypesInGrp(pk_group);
    if (CollectionUtils.isEmpty(typeAndTrantypeList)) {
      return null;
    }
    Set<String> ttSet = new HashSet<String>(Arrays.asList(trantypecode));
    Map<String, String> map = new HashMap<String, String>();
    for (BilltypeVO vo : typeAndTrantypeList) {
      if (ttSet.contains(vo.getPk_billtypecode())) {
        map.put(vo.getPk_billtypecode(), vo.getPk_billtypeid());
      }
    }
    return map;
  }

  /**
   * 方法功能描述:得到单据类型对应的所有交易类型。
   * <p>
   * <b>参数说明</b>
   * 
   * @param billtype
   * @return <p>
   * @since 6.0
   * @author zhaoyha
   * @time 2010-4-12 下午02:55:39
   */
  public static String[] getTrantypes(String billtype, String pk_group) {
    List<String> trantypeList = new ArrayList<String>();
    List<BilltypeVO> typeAndTrantypeList =
        PfDataCache.getBillTypeAndTranstypesInGrp(pk_group);
    if (!CollectionUtils.isEmpty(typeAndTrantypeList)) {
      for (BilltypeVO btvo : typeAndTrantypeList) {
        UFBoolean trantypeFlag = btvo.getIstransaction();
        String parentType = btvo.getParentbilltype();
        if (UFBoolean.TRUE.equals(trantypeFlag) && billtype.equals(parentType)) {
          trantypeList.add(btvo.getPk_billtypecode());
        }
      }
    }
    return trantypeList.toArray(new String[trantypeList.size()]);
  }

  /**
   * 判断某用户对某个单据或交易类型是否有可启动的流程定义
   * 
   * @param billOrTranstype 单据或交易类型
   * @param pkOrg 组织PK
   * @param operator 用户PK
   * @param iWorkflowOrApproveflow 主流程类型,见
   *          <code>WorkflowTypeEnum.Approveflow</code>和
   *          <code>WorkflowTypeEnum.Workflow</code>
   * @return
   * @throws BusinessException
   */
  public static boolean isExistWorkflowDefinition(String billOrTranstype,
      String pkOrg, String operator, int iWorkflowOrApproveflow) {
    try {
      return NCLocator
          .getInstance()
          .lookup(IPFWorkflowQry.class)
          .isExistWorkflowDefinition(billOrTranstype, pkOrg, operator,
              iWorkflowOrApproveflow);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return false;
  }

  /**
   * 支持修订走审批流的场景
   * 
   * @param billOrTranstype
   * @param pkOrgemend
   * @param operator
   * @param emend 修订状态
   * @param iWorkflowOrApproveflow
   * @return
   */
  public static boolean isExistWorkflowDefinitionEmend(String billOrTranstype,
      String pkOrg, String operator, int emend, int iWorkflowOrApproveflow) {
    try {
      return NCLocator
          .getInstance()
          .lookup(IPFWorkflowQry.class)
          .isExistWorkflowDefinitionWithEmend(billOrTranstype, pkOrg, operator,
              emend, iWorkflowOrApproveflow);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return false;
  }

  /**
   * 方法功能描述:是否流程单据
   * <p>
   * <b>参数说明</b>
   * 
   * @param billtype
   * @return <p>
   * @since 6.0
   * @author yangb
   * @time 2010-9-12 上午12:06:48
   */
  public static boolean isFlowBilltype(String billtype) {
    BilltypeVO typevo = PfDataCache.getBillType(billtype);
    if (typevo == null) {
      return false;
    }
    return typevo.getIsBizflowBill() == null ? false : typevo
        .getIsBizflowBill().booleanValue();
  }

  /**
   * 流程平台进行的单据动作批处理的入口类. <li>数据加锁和一致性检查 <li>动作执行IPFBusiAction <li>
   * 该接口是远程public接口,无事务,为了保证锁和事务的一致性,特提供该接口 <li>平台默认调用该接口
   * 
   * @param actionName
   * @param billType
   * @param currentDate
   * @param worknoteVO
   * @param billvos
   * @param userObjAry
   * @param eParam
   * @return
   * @throws BusinessException <p>
   * @since 6.0
   * @author zhangcheng
   * @time 2010-4-15 下午15:00:32
   */
  public static Object processBatch(String actionName, String billType,
      AggregatedValueObject[] billvos, Object[] userObjAry,
      WorkflownoteVO worknoteVO) {
    try {
      // IPFBusiAction 是UAP流程平台文档公布的后台调脚本类
      return NCLocator
          .getInstance()
          .lookup(IPFBusiAction.class)
          .processBatch(actionName, billType, billvos, userObjAry, worknoteVO,
              null);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 获取转单时对应的流程配置中对应的交易类型,并赋给当前VO
   * 
   * @param bills
   * @param pk_destbilltype 下游单据类型
   * @author chenyyb
   */
  public static void processDestBillTranType(IBill[] bills,
      String pk_destbilltype, String pk_group) {
    if (bills == null || bills.length == 0) {
      return;
    }
    for (IBill bill : bills) {
      PfServiceScmUtil.processDestBillTranType(bill, pk_destbilltype, pk_group);
    }
  }

  /**
   * 查询集团下某业务流程中所有单据的VO数组
   * 
   * @param biz 业务类型PK
   * @param pk_group 业务类型PK,如果为空,则返回所有流程配置中该单据的下游单据
   * @return BillbusinessVO[]
   * @throws BusinessException
   * @author 刘志伟
   */
  public static BillbusinessVO[] queryAllBillBusiVO(String biz, String pk_group) {
    try {
      return NCLocator.getInstance().lookup(IPFConfig.class)
          .findBillbusinessVOs(biz, pk_group);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 返回源动作可驱动的动作
   * 
   * @param sourceBillType 源单据类型PK
   * @param sourceBusiType 源业务类型PK
   * @param sourceAction 源单据动作编码
   * @return nc.vo.pub.pfflow04.MessagedriveVO[]
   * @throws BusinessException <p>
   * @since 6.0
   * @author zhangcheng
   * @time 2010-4-15 下午15:00:32
   */
  public static MessagedriveVO[] queryAllMsgdrvVOs(String sourceBillType,
      String sourceBusiType, String sourceAction) {
    try {
      return NCLocator.getInstance().lookup(IPFMetaModel.class)
          .queryAllMsgdrvVOs(sourceBillType, sourceBusiType, sourceAction);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 查询某业务流程中某单据的下游单据VO数组
   * 
   * @param billType 单据类型PK
   * @param busiType 业务类型PK,如果为空,则返回所有流程配置中该单据的下游单据
   * @return 下游单据VO数组
   * @throws BusinessException
   */
  public static BillbusinessVO[] queryBillDest(String billType, String busiType) {
    try {
      return NCLocator.getInstance().lookup(IPFConfig.class)
          .queryBillDest(billType, busiType);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  /**
   * 查询某业务类型下某单据类型(或交易类型)的所有来源单据VO数组 <li>不包含间接来源关系 <li>如果是自制单据,也额外作为一个VO返回
   * 
   * @param groupId 集团PK
   * @param billOrTranstype 单据类型或者交易类型
   * @param businessType 业务类型PK
   * @param isQueryBillType 如果为交易类型,是否返回所属单据类型的来源
   * @return 来源单据VO数组
   * @throws BusinessException <p>
   * @since 6.0
   * @author tianft
   * @time 2010-4-7 下午10:20:32
   */
  public static BillbusinessVO[] querybillSource(String groupId,
      String billOrTranstype, String businessType, boolean includeBillType) {
    try {
      return NCLocator
          .getInstance()
          .lookup(IPFConfig.class)
          .querybillSource(groupId, billOrTranstype, businessType,
              includeBillType);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return null;
  }

  public static int queryFlowStatus(String billOrTranstype, String billId,
      int iWorkflowOrApproveflow) {
    try {
      return NCLocator.getInstance().lookup(IPFWorkflowQry.class)
          .queryFlowStatus(billOrTranstype, billId, iWorkflowOrApproveflow);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);

    }
    return -1;
  }

  /**
   * 注册根据四要素确定业务流程,远程调用合并的处理信息
   * 
   * @param billtype
   * @param transtype
   * @param pk_org
   * @param userid
   * @return
   */
  public static Token register_getBusitype(String billtype, String transtype,
      String pk_org, String userid) {
    RemoteCallCombinatorEx rcc = RemoteCallCombinatorEx.getInstance();
    try {
      IPFConfig conf = rcc.getService(IPFConfig.class);
      conf.retBusitypeCanStart(billtype, transtype, pk_org, userid);
    }
    catch (BusinessException e) {
      // 日志异常
      ExceptionUtils.wrappException(e);
    }
    return rcc.getToken();
  }

  /**
   * 方法功能描述:查询并设置流程相关单据的业务流程(业务类型)。
   * <p>
   * 根据4个要素:组织,交易(单据类型),交易类型,用户来确认一个流程<br>
   * 如果单据中已经有业务流程,则方法中不再重设置<br>
   * 匹配不到流程,则抛错<br>
   * <p>
   * <b>参数说明</b>
   * 
   * @param bills 单据聚合VO数组
   * @param billType 单据类型
   *          <p>
   * @since 6.0
   * @author zhaoyha
   * @time 2010-1-29 下午02:37:57
   */
  public static void setBusiType(IBill[] bills, String billType) {
    if (null == bills || 0 == bills.length) {
      return;
    }
    try {
      for (IBill bill : bills) {
        IFlowBizItf fbi =
            PfMetadataTools.getBizItfImpl(bill, IFlowBizItf.class);
        if (null == fbi) {
          ExceptionUtils.unSupported();
          return;
        }
        if (!StringUtil.isEmptyWithTrim(fbi.getBusitype())) {
          // 如果已经有业务流程,则不重新查找
          continue;
        }
        String busitypeName = fbi.getColumnName(IFlowBizItf.ATTRIBUTE_BUSITYPE);
        String pk_org = fbi.getPkorg();
        String transtype = fbi.getTranstype();
        String userid = fbi.getBillMaker();
        userid =
            StringUtils.isBlank(userid) ? AppContext.getInstance().getPkUser()
                : userid;
        String busitype =
            NCLocator.getInstance().lookup(IPFConfig.class)
                .retBusitypeCanStart(billType, transtype, pk_org, userid);
        if (StringUtil.isEmptyWithTrim(busitype)) {
          ExceptionUtils.wrappBusinessException(nc.vo.ml.NCLangRes4VoTransl
              .getNCLangRes().getStrByID("4001002_0", "04001002-0414")/*
                                                                       * @res
                                                                       * "没有找到对应的业务流程,请检查!"
                                                                       */);
        }
        // 设置新的流程
        bill.getParent().setAttributeValue(busitypeName, busitype);
      }
    }
    catch (Exception e) {
      ExceptionUtils.wrappException(e);
    }
  }

  /**
   * 方法功能描述:查询并设置流程相关单据的业务流程(业务类型)。
   * <p>
   * 根据4个要素:组织,交易(单据类型),交易类型,用户来确认一个流程<br>
   * 如果单据中已经有业务流程,则方法中不再重设置<br>
   * 匹配不到流程,不抛错<br>
   * <p>
   * <b>参数说明</b>
   * 
   * @param bills 单据聚合VO数组
   * @param billType 单据类型
   *          <p>
   * @since 6.0
   * @author zhaoyha
   * @time 2010-1-29 下午02:37:57
   */
  public static void setBusiTypeNoExcep(IBill[] bills, String billType) {
    if (null == bills || 0 == bills.length) {
      return;
    }
    try {
      for (IBill bill : bills) {
        IFlowBizItf fbi =
            PfMetadataTools.getBizItfImpl(bill, IFlowBizItf.class);
        if (null == fbi) {
          ExceptionUtils.unSupported();
          return;
        }
        if (!StringUtil.isEmptyWithTrim(fbi.getBusitype())) {
          // 如果已经有业务流程,则不重新查找
          continue;
        }
        String busitypeName = fbi.getColumnName(IFlowBizItf.ATTRIBUTE_BUSITYPE);
        String pk_org = fbi.getPkorg();
        String transtype = fbi.getTranstype();
        String userid = fbi.getBillMaker();
        userid =
            StringUtils.isBlank(userid) ? AppContext.getInstance().getPkUser()
                : userid;
        String busitype =
            NCLocator.getInstance().lookup(IPFConfig.class)
                .retBusitypeCanStart(billType, transtype, pk_org, userid);
        if (!StringUtil.isEmptyWithTrim(busitype)) {
          // 设置新的流程
          bill.getParent().setAttributeValue(busitypeName, busitype);
        }

      }
    }
    catch (Exception e) {
      ExceptionUtils.wrappException(e);
    }
  }

  /**
   * 根据单据类型来过滤交易类型VO
   * 
   * @param busiVOs
   * @param billtype
   * @param transtype
   * @return
   * @author chenyyb
   */
  private static List<BillbusinessVO> filterBusiVOByBilltype(
      BillbusinessVO[] busiVOs, String pk_destbilltype) {
    List<BillbusinessVO> retBusiVOs = new ArrayList<BillbusinessVO>();
    for (BillbusinessVO busiVO : busiVOs) {
      if (StringUtils.isEmpty(pk_destbilltype)) {
        continue;
      }
      if (pk_destbilltype.equals(busiVO.getPk_billtype())) {
        retBusiVOs.add(busiVO);
      }
    }
    return retBusiVOs;
  }

  private static String getDestTrantypeByBillItfDef(String sourceType,
      String sourceTTPK, String desType, String defualtDesTrantype) {
    TransTypeMapping mapping = new TransTypeMapping();
    mapping.setSrcBillType(sourceType);
    mapping.setSrcTransType(sourceTTPK);
    mapping.setDestBillType(desType);
    String destTT =
        PfBillItfDefUtil.queryTransTypeMapping(
            AppContext.getInstance().getPkGroup(), mapping)
            .getDestTransTypeCode();
    destTT =
        StringUtils.isNotBlank(destTT) ? destTT : StringUtils
            .isNotBlank(defualtDesTrantype) ? defualtDesTrantype : desType;
    return destTT;
  }

  private static MapList<String, AggregatedValueObject> getTrantypeVOMap(
      AggregatedValueObject[] sourceVos) {
    MapList<String, AggregatedValueObject> ttVoMap =
        new MapList<String, AggregatedValueObject>();
    for (AggregatedValueObject srcVo : sourceVos) {
      String srcTT = PfServiceScmUtil.getBizItfImpl(srcVo).getTranstypePk();
      ttVoMap.put(srcTT, srcVo);
    }
    return ttVoMap;
  }

  private static void processDestBillTranType(IBill bill,
      String pk_destbilltype, String pk_group) {
    if (bill == null) {
      return;
    }
    IFlowBizItf fbi = PfServiceScmUtil.getBizItfImpl(bill);
    // 业务类型
    String busitype = fbi.getBusitype();
    if (StringUtil.isEmptyWithTrim(busitype)) {
      return;
    }
    BillbusinessVO[] busiVOs =
        PfServiceScmUtil.findBillbusinessVOs(busitype, pk_group);
    if (busiVOs == null) {
      return;
    }
    List<BillbusinessVO> filterBusiVOs =
        PfServiceScmUtil.filterBusiVOByBilltype(busiVOs, pk_destbilltype);
    if (filterBusiVOs.size() == 0) {
      return;
    }
    // 设置交易类型、交易类型pk
    String transtype = filterBusiVOs.get(0).getTranstype();
    String transtypePk = PfServiceScmUtil.getTrantypeidByCode(new String[] {
      transtype
    }).get(transtype);
    if (!StringUtil.isEmptyWithTrim(transtype)) {
      fbi.setTranstype(transtype);
    }
    if (!StringUtil.isEmptyWithTrim(transtypePk)) {
      fbi.setTranstypePk(transtypePk);
    }
  }

}

NC 调用动作脚本推单据(这里以销售订单为例):

// 保存
SaleOrderVO[] retvos = (SaleOrderVO[]) PfServiceScmUtil.processBatch(SOConstant.WRITE,SOBillType.Order.getCode(), combinBillVOs, null, null);

//审批 
retvos = (SaleOrderVO[]) PfServiceScmUtil.processBatch(SOConstant.APPROVE, SOBillType.Order.getCode(), combinBillVOs, null, null);

销售管理常量类

package nc.vo.so.pub;

import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;

/**
 * 销售管理常量类
 * 
 * @since 6.0
 * @version 2011-12-2 上午09:03:34
 * @author fengjb
 */
public class SOConstant {

  /**
   * 订单关闭管理查询最大的行数
   */
  public static final int CLOSEMANAGEMAXROWS = 5001;

  /**
   * 审批动作脚本标识
   */
  public static final String APPROVE = "APPROVE";

  /**
   * 保存动作标示
   */
  public static final String WRITE = "WRITE";

  /** 删除动作标示*/
  public static final String DELETE = "DELETE";

  /** 标准重量单位 */
  public static final String BD305 = "BD305";
  
  /**
   * 标准体积单位
   */
  public static final String BD304="BD304";

  public static final String AGGFFILEVO = "aggffilevo";

  public static final String SO_BATCHCODE_PATH =
      "nc/ui/so/pub/model/so_batchcode.xml";

  public static final String[] ONHANDDLG_BODY_KEY = new String[] {
    SOItemKey.CMATERIALVID, SOItemKey.CASTUNITID, SOItemKey.VBATCHCODE,
    SOItemKey.VCHANGERATE, SOItemKey.CPROJECTID, SOItemKey.CPRODUCTORID,
    SOItemKey.CVENDORID, SOItemKey.CMFFILEID, SOItemKey.VFREE1,
    SOItemKey.VFREE2, SOItemKey.VFREE3, SOItemKey.VFREE4, SOItemKey.VFREE5,
    SOItemKey.VFREE6, SOItemKey.VFREE7, SOItemKey.VFREE8, SOItemKey.VFREE9,
    SOItemKey.VFREE10,
  };

  /**
   * 销售发票支持批改的字段
   */
  public static final String[] DELIVERYFILLENABLEDKEY = new String[] {
    // 仓库
    SOItemKey.CSENDSTORDOCID,
    // 发货日期、押运员、承运商、车型、车辆
    SOItemKey.DSENDDATE, SOItemKey.CSUPERCARGOID, SOItemKey.CTRANSCUSTID,
    SOItemKey.CVEHICLETYPEID, SOItemKey.CVEHICLEID
  };

  /**
   * 销售订单和预定支持批改的字段
   */
  public static final String[] FILLENABLEDKEY = new String[] {
    // 赠品标志(V635新增-索芙特项目)
    SOItemKey.BLARGESSFLAG,
    // 汇率、
    SOItemKey.NEXCHANGERATE,
    // 税率
    SOItemKey.NTAXRATE,
    // 单品折扣、主含税单价、主无税单价
    SOItemKey.NITEMDISCOUNTRATE,
    SOItemKey.NORIGTAXPRICE,
    SOItemKey.NORIGPRICE,
    // 主含税净价、主无税净价、含税单价
    SOItemKey.NORIGTAXNETPRICE,
    SOItemKey.NORIGNETPRICE,
    SOItemKey.NQTORIGTAXPRICE,
    // 无税单价、含税净价、无税净价
    SOItemKey.NQTORIGPRICE,
    SOItemKey.NQTORIGTAXNETPRC,
    SOItemKey.NQTORIGNETPRICE,

    // 发货库存组织、仓库、发货日期、收货客户、收货地区、收货地点、收货地址、到货日期
    // 项目、备注
    SOItemKey.CSENDSTOCKORGVID, SOItemKey.CSENDSTORDOCID, SOItemKey.DSENDDATE,
    SOItemKey.CRECEIVECUSTID, SOItemKey.CRECEIVEAREAID,
    SOItemKey.CRECEIVEADDDOCID, SOItemKey.CRECEIVEADDRID,
    SOItemKey.DRECEIVEDATE, SOItemKey.CPROJECTID, SOItemKey.VROWNOTE
  };

  /** 我的订单列表模板ID */
  public static final String MYORDER_BILLTEMPLET = "1005Z8100000000054EZ";

  /** 折扣默认值100 */
  public static final UFDouble ONEHUNDRED = new UFDouble(100);

  /** 操作失败 */
  public static final String OPRETAION_FAIL = "1";

  /** 操作成功 */
  public static final String OPRETAION_SUCCESS = "0";

  /** 我的订单明细模板ID */
  public static final String ORDERDTL_BILLTEMPLET = "1005Z8100000000058A4";

  /** 点分隔符 */
  public static final String POINT = ".";

  /** 取权限需要的常量(操作编码) */
  public static final String PSNDOC = "psndoc";

  /**
   * 销售发票支持批改的字段
   */
  public static final String[] SALEINVOICEFILLENABLEDKEY = new String[] {
    // 主含税单价、主无税单价
    SOItemKey.NORIGTAXPRICE,
    SOItemKey.NORIGPRICE,
    // 主含税净价、主无税净价、含税单价
    SOItemKey.NORIGTAXNETPRICE, SOItemKey.NORIGNETPRICE,
    SOItemKey.NQTORIGTAXPRICE,
    // 无税单价、含税净价、无税净价
    SOItemKey.NQTORIGPRICE, SOItemKey.NQTORIGTAXNETPRC,
    SOItemKey.NQTORIGNETPRICE,

    // 仓库
    SOItemKey.CSENDSTORDOCID,
  };

  /** 取权限需要的常量(资源权限实体编码) */
  public static final String SCMDEFAULT = "SCMDefault";

  /**
   * 需要触发单价金额算法的字段
   */
  public static final String[] STRNEEDCALKEY = new String[] {
    // 数量、主数量、换算率
    SOItemKey.NASTNUM,
    SOItemKey.NNUM,
    SOItemKey.VCHANGERATE,
    // 单位
    SOItemKey.CASTUNITID,
    // 报价单位数量、报价换算率、税率
    SOItemKey.NQTUNITNUM,
    SOItemKey.VQTUNITRATE,
    SOItemKey.NTAXRATE,
    // 整单折扣、单品折扣、主含税单价、主无税单价
    SOItemKey.NDISCOUNTRATE,
    SOItemKey.NITEMDISCOUNTRATE,
    SOItemKey.NORIGTAXPRICE,
    SOItemKey.NORIGPRICE,
    // 主含税净价、主无税净价、含税单价
    SOItemKey.NORIGTAXNETPRICE,
    SOItemKey.NORIGNETPRICE,
    SOItemKey.NQTORIGTAXPRICE,
    // 无税单价、含税净价、无税净价
    SOItemKey.NQTORIGPRICE,
    SOItemKey.NQTORIGTAXNETPRC,
    SOItemKey.NQTORIGNETPRICE,
    // 税额、无税金额、价税合计
    SOItemKey.NTAX, SOItemKey.NORIGMNY, SOItemKey.NORIGTAXMNY, SOItemKey.NMNY,
    SOItemKey.NTAXMNY,
    // 折扣额、折本汇率
    SOItemKey.NORIGDISCOUNT, SOItemKey.NEXCHANGERATE,
    // 集团本位币汇率、全局本位币汇率、扣税类别、计税金额
    SOItemKey.NGROUPEXCHGRATE, SOItemKey.NGLOBALEXCHGRATE,
    SOItemKey.FTAXTYPEFLAG, SOItemKey.NCALTAXMNY
  };

  /** 结束日期默认值 */
  public static final UFDate SYSENDDATE = new UFDate("2099-12-31");

  /** 报表展示的单据日期变量 */
  public static final String VAR_DBILLDATE = "var_dbilldate";

  /** 报表展示的业务日期变量 */
  // public static final String VAR_DBUSIDATE = "var_dbusidate";

  /** 表体自定义项前缀 */
  public static final String VBDEF = "vbdef";

  /** 表头自定义项前缀 */
  public static final String VDEF = "vdef";

}

销售管理库表枚举类

package nc.vo.so.pub;

/**
 * 销售管理库表枚举类
 * 
 * @since 6.1
 * @version 2012-11-29 09:29:07
 * @author 冯加彬
 */
public enum SOTable {

  /**
   * 买赠主表
   */
  BUYLARGESS("so_buylargess"),
  /**
   * 买赠子表
   */
  BUYLARGESS_B("so_buylargess_b"),
  /**
   * 报价单交易类型
   */
  SALEQUOTATIONTYPE("so_salequotationtype"),

  /**
   * 报价单主表
   */
  SALEQUOTATION("so_salequotation"),

  /**
   * 报价单子表
   */
  SALEQUOTATION_B("so_salequotation_b"),

  /**
   * 预订单交易类型
   */
  M38TRANTYPE("so_m38trantype"),

  /**
   * 预订单主表
   */
  PREORDER("so_preorder"),

  /**
   * 预订单子表
   */
  PREORDER_B("so_preorder_b"),

  /**
   * 销售订单主表
   */
  SALEORDER("so_saleorder"),

  /**
   * 销售订单子表
   */
  SALEORDER_B("so_saleorder_b"),

  /**
   * 销售订单执行表
   */
  SALEORDER_EXE("so_saleorder_exe"),

  /**
   * 销售订单修订主表
   */
  ORDERHISTORY("so_orderhistory"),

  /**
   * 销售订单修订子表
   */
  ORDERHISTORY_B("so_orderhistory_b"),

  /**
   * 发货单主表
   */
  DELIVERY("so_delivery"),

  /**
   * 发货单子表
   */
  DELIVERY_B("so_delivery_b"),

  /**
   * 发货单质检表
   */
  DELIVERY_CHECK("so_delivery_check"),

  /**
   * 销售发票主表
   */
  SALEINVOICE("so_saleinvoice"),

  /**
   * 销售发票子表
   */
  SALEINVOICE_B("so_saleinvoice_b"),

  /**
   * 销售发票结算单主表
   */
  SQUAREINV("so_squareinv"),

  /**
   * 销售发票结算单子表
   */
  SQUAREINV_B("so_squareinv_b"),

  /**
   * 销售发票结算单明细表
   */
  SQUAREINV_D("so_squareinv_d"),

  /**
   * 销售出库结算单主表
   */
  SQUAREOUT("so_squareout"),

  /**
   * 销售出库结算单子表
   */
  SQUAREOUT_B("so_squareout_b"),

  /**
   * 销售出库结算单明细表
   */
  SQUAREOUT_D("so_squareout_d"),

  /**
   * 途损结算单主表
   */
  SQUAREWAS("so_squarewas"),

  /**
   * 途损结算单子表
   */
  SQUAREWAS_B("so_squarewas_b"),

  /**
   * 途损结算单明细表
   */
  SQUAREWAS_D("so_squarewas_d"),

  /**
   * 销售公用ID临时表1
   * 使用场景:数组字段超过200时公共临时表名
   */
  TMP_SO_ID1("tmp_so_id1"),
  /**
   * 销售公用ID临时表2
   * 使用场景:同时有两个数组字段超过200时第2个公共临时表名
   */
  TMP_SO_ID2("tmp_so_id2"),

  /**
   * 退货政策匹配参数临时表
   * 使用场景:退货政策匹配时存放扩展参数
   */
  TMP_SO_RETURNASSIGN("tmp_so_retasgn61"),

  /**
   * 销售组织ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放销售组织参数
   */
  TMP_SO_SALEORG("tmp_so_saleorg"),

  /**
   * 订单类型ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放订单类型参数
   */
  TMP_SO_ORDERTYPE("tmp_so_ordertype"),

  /**
   * 订单客户ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放订单客户参数
   */
  TMP_SO_ORDERCUST("tmp_so_ordercust"),

  /**
   * 开票客户ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放开票客户参数
   */
  TMP_SO_INVCUST("tmp_so_invcust"),

  /**
   * 结算方式ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放结算方式参数
   */
  TMP_SO_BALTYPE("tmp_so_baltype"),
  /**
   * 价格项ID临时表
   * 使用场景:销售订单、发票、订单收款核销为返利提供取数函数时,存放价格项参数
   */
  TMP_SO_PRCITEM("tmp_so_prcitem"),
  /**
   * 计划独立需求使用临时表
   * 使用场景:计划独立需求存放生产制造参数
   */
//  TMP_SO_PID("tmp_so_pid"), for V636 由于临时表增加了一个特征码维度,所以需要修改表名 jilu
  TMP_SO_PID("tmp_so_pid2"),
  /**
   * 订单毛利分析分页临时表
   * 使用场景:订单毛利分析报表存放分页订单明细数据
   */
  TMP_SO_ORDERPFPAGE("tmp_so_orderpfpage"),
  /**
   * 订单毛利分析数据加工结果临时表
   * 使用场景:订单毛利分析报表存放毛利计算结果数据
   */
  TMP_SO_ORDERPROFIT("tmp_so_orderprofit"),
  /**
   * 出库毛利分析分页临时表
   * 使用场景:出库毛利分析报表存放分页出库单明细数据
   */
  TMP_SO_OUTPFPAGE("tmp_so_outpfpage"),
  /**
   * 出库毛利分析数据加工结果临时表
   * 使用场景:出库毛利分析报表存放毛利计算结果数据
   */
  TMP_SO_OUTPROFIT("tmp_so_outprofit"),

  /**
   * 订单执行汇总分页临时表
   * 使用场景:订单执行汇总报表存放分页订单明细数据
   */
  TMP_SO_ORDERSUMPAGE("tmp_so_ordersumpage"),
  /**
   * 订单执行汇总数据加工结果临时表
   * 使用场景:订单执行汇总表存放数据加工执行结果数据
   */
  TMP_SO_ORDERSUMMARY("tmp_so_ordersummary"),
  /**
   * 发票执行汇总分页临时表
   * 使用场景:发票执行汇总报表存放分页发票明细数据
   */
  TMP_SO_INVSUMPAGE("tmp_so_invsumpage"),
  /**
   * 发票执行汇总数据加工结果临时表
   * 使用场景:发票执行汇总表存放数据加工执行结果数据
   */
  TMP_SO_INVSUMMARY("tmp_so_invsummary"),
  /**
   * 出库执行汇总分页临时表
   * 使用场景:出库执行汇总报表存放分页出库明细数据
   */
  TMP_SO_OUTSUMPAGE("tmp_so_outsumpage"),
  /**
   * 出库执行汇总数据加工结果临时表
   * 使用场景:出库执行汇总表存放数据加工执行结果数据
   */
  TMP_SO_OUTSUMMARY("tmp_so_outsummary"),
  /**
   * 综合毛利分析数据加工结果临时表
   * 使用场景:综合毛利分析报表存放数据加工执行结果数据
   */
  TMP_SO_MULTIPLEPROFIT("tmp_so_multprofit"),
  /**
   * 买赠匹配使用临时表
   * 使用场景:买赠匹配存放匹配参数
   */
  TMP_SO_LARMATCH("tmp_so_larmatch"),

  TMP_SO_PRCPROMTYPE("tmp_so_prcpromtype");

  private String name;

  private SOTable(String name) {
    this.name = name;
  }

  /**
   * 获得表名
   * 
   * @return 表名
   */
  public String getName() {
    return this.name;
  }
}

销售管理单据类型

package nc.vo.scmpub.res.billtype;

/**
 * 销售管理单据类型
 * 
 * @since 6.0
 * @version 2010-1-29 下午02:26:22
 * @author 张成
 */
public enum SOBillType implements IBillType {

  /**
   * 冲应收单
   */
  Arsub("35", "4001002_0", "04001002-0517"/*@res "费用冲抵单"*/),

  /**
   * 发货单
   */
  Delivery("4331", "4001002_0", "04001002-0518"/*@res "发货单"*/),

  /**
   * 销售发票
   */
  Invoice("32", "4001002_0", "04001002-0519"/*@res "销售发票"*/),

  /**
   * 销售订单
   */
  Order("30", "4001002_0", "04001002-0520"/*@res "销售订单"*/),
  
  /**
   * 销售订单
   */
  Order30R("30R", "4001002_0", "04001002-0520"/*@res "销售修订"*/),

  /**
   * 配置BOM单
   */
  OrderBom("3M", "4001002_0", "04001002-0521"/*@res "配置BOM单"*/),

  /**
   * 预订单
   */
  PreOrder("38", "4001002_0", "04001002-0522"/*@res "预订单"*/),

  /**
   * 销售报价单
   */
  SaleQuotation("4310", "4001002_0", "04001002-0523"/*@res "销售报价单"*/),

  /**
   * 销售发票待结算单
   */
  SquareInvoice("4332", "4001002_0", "04001002-0524"/*@res "销售发票待结算单"*/),

  /**
   * 销售出库待结算单
   */
  SquareOut("434C", "4001002_0", "04001002-0525"/*@res "销售出库待结算单"*/),
  /**
   * 途损待结算单
   */
  SquareWas("4353", "4001002_0", "04001002-0526"/*@res "途损待结算单"*/);

  // 单据类型
  private String code;

  // 单据名称
  private String name;

  private String resCommon;

  private String resId;

  private SOBillType(String code, String resCommon, String resId) {
    this.code = code;
    this.resCommon = resCommon;
    this.resId = resId;
  }

  @Override
  public String getCode() {
    return this.code;
  }

  @Override
  public String getName() {
    return nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
        this.resCommon, this.resId);
  }

  @Override
  public boolean isEqual(String pcode) {
    return this.code.equals(pcode);
  }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值