/**
* $文件说明$
*
* @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);
}
}