目录
3.5、校验文件管理内无法打开新注册接口单据类型的xml模板
前言
通常情况下,第三方系统往NC系统推送单据我们一般会用数据交换平台(集成平台)做接口开发。但是系统本身支持的单据并不全,这个时候我们就需要做一些外部交换平台单据接口开发功能了,接下来我们将介绍单据开发详细步骤过程。
1、插件开发向导
新增单据接口开发过程全部在此节点,是重中之重,该过程下又细分以下小节点。
1.1、单据插件信息注册
说明:
===模块信息===
【模块名】:
单据所属模块,比如物资及服务需求单属于”pmr”模块,凭证属于”gl”模块,模块会影响交换插件最终的部署位置。
===插件配置===
【单据标识】:
一般填写相应的单据类型即可,如果没有单据类型,比如基础档案,可以取一个能唯一标识当前档案的名称。比如部门档案取名为”bmdept”。
【单据描述】:
一般写单据的名称或者简单的功能描述。
【元数据实体】:
单据对应在NC系统中的元数据实体。
【VO类名称】:
VO类名称,通过输入的VO生成交换规则。
【VO类名称】:
VO类名称,通过输入的VO生成交换规则。注意:必须实现SuperVO。
【单据加锁级别】:
选择框,锁的控制级别,用户控制并发问题,对于大多数单据,如果没有特别的要求,保持默认值即可。
【插件类名称】:
针对该单据,最终的插件处理类名称。这里插件类需要遵循特定的接口。参考代码请看下边代码示例。
【应用资产层次选择】:
选择框,可设置领域级。检验文件管理处配置文件需对应此处层级。

示例代码:
package nc.bs.pbm.plugin;
import org.apache.commons.lang.StringUtils;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.bs.pfxx.ISwapContext;
import nc.bs.pfxx.plugin.AbstractPfxxPlugin;
import nc.bs.trade.business.HYPubBO;
import nc.itf.pbm.materialplan.pvt.IMaterialPlanInterface;
import nc.vo.pbm.materialplan.MaterialPlanBillVO;
import nc.vo.pbm.materialplan.MaterialPlanBodyVO;
import nc.vo.pbm.materialplan.MaterialPlanHeadVO;
import nc.vo.pfxx.auxiliary.AggxsysregisterVO;
import nc.vo.pfxx.util.PfxxPluginUtils;
import nc.vo.pmpub.project.ProjectHeadVO;
import nc.vo.pub.BusinessException;
public class MaterialPlanPfxxPlugin extends AbstractPfxxPlugin {
private IMaterialPlanInterface service = null;
@Override
protected Object processBill(Object vo, ISwapContext swapContext,
AggxsysregisterVO aggxsysvo) throws BusinessException {
// TODO Auto-generated method stub
if (vo == null) {
return null;
}
String pk = null;
MaterialPlanBillVO aggVO = (MaterialPlanBillVO) vo;
MaterialPlanHeadVO hvo = aggVO.getParentVO();
MaterialPlanBodyVO[] bvos = (MaterialPlanBodyVO[]) aggVO
.getChildrenVO();
hvo.setHdef2("SS");
// 字段校验
if (bvos == null) {
throw new BusinessException("明细数据不能为空!");
}
if (hvo.getPk_project() == null) {
throw new BusinessException("项目不能为空!");
}
if (hvo.getPk_org() == null || hvo.getPk_org_v() == null) {
throw new BusinessException("项目组织不能为空!");
}
if (hvo.getBillmaker() == null || hvo.getCreator() == null) {
throw new BusinessException("制单人或创建人不能为空!");
}
if (hvo.getBillmaketime() == null || hvo.getCreationtime() == null) {
throw new BusinessException("制单或创建人不能为空!");
}
if (hvo.getReq_make_date() == null) {
throw new BusinessException("需求编制日期不能为空!");
}
if (hvo.getBusi_type() == null || hvo.getTransi_type() == null
|| hvo.getPk_transitype() == null) {
throw new BusinessException("单据类型或交易类型不能为空!");
}
if (hvo.getPk_currtype() == null) {
throw new BusinessException("币种不能为空!");
}
if (hvo.getContr_version() == null
|| hvo.getContr_version().toDouble() != 1) {
throw new BusinessException("表头当前版本必须等于1!");
}
for (MaterialPlanBodyVO bvo : bvos) {
if (bvo.getRowno() == null) {
throw new BusinessException("行号不能为空!");
}
if (bvo.getPk_cbs_node() == null) {
throw new BusinessException("CBS不能为空!");
}
if (bvo.getPk_stockorg() == null) {
throw new BusinessException("库存组织不能为空!");
}
if (bvo.getPk_stockorg_v() == null) {
throw new BusinessException("库存组织版本不能为空!");
}
if (bvo.getNnum() == null) {
throw new BusinessException("数量不能为空!");
}
if (bvo.getPk_material() == null || bvo.getPk_material_v() == null) {
throw new BusinessException("物料不能为空!");
}
}
// 原项目
ProjectHeadVO oldvo = (ProjectHeadVO) new HYPubBO().queryByPrimaryKey(
ProjectHeadVO.class, hvo.getPk_project());
// 重新翻译项目
ProjectHeadVO[] newprojectVO = (ProjectHeadVO[]) new HYPubBO()
.queryByCondition(
ProjectHeadVO.class,
" 1= 1 and pk_duty_org = '" + hvo.getPk_org()
+ "' and project_code = '"
+ oldvo.getProject_code() + "'");
hvo.setPk_project(newprojectVO[0].getPrimaryKey());
for (int i = 0; i < bvos.length; i++) {
bvos[i].setPk_project(newprojectVO[0].getPrimaryKey());
}
try {
pk = PfxxPluginUtils.queryBillPKBeforeSaveOrUpdate(
swapContext.getBilltype(), swapContext.getDocID());
if (StringUtils.isBlank(pk)) {
aggVO = insertMaterialPlanBillVO(aggVO);
return aggVO.getPrimaryKey();
} else {
throw new BusinessException("暂不支持修改功能!");
}
} catch (Exception ex) {
Logger.error(ex.getMessage(), ex.getCause());
throw new BusinessException(ex.getMessage(), ex.getCause());
}
}
private MaterialPlanBillVO insertMaterialPlanBillVO(MaterialPlanBillVO aggVO)
throws BusinessException {
// TODO Auto-generated method stub
MaterialPlanBillVO[] aggvos = getService().insertMaterialPlanVOS(
new MaterialPlanBillVO[] { aggVO });
return aggvos == null ? null : aggvos[0];
}
private IMaterialPlanInterface getService() {
if (this.service == null) {
this.service = ((IMaterialPlanInterface) NCLocator.getInstance()
.lookup(IMaterialPlanInterface.class));
}
return this.service;
}
}
1.2、校验文件配置信息
配置好单据注册相关信息后,就可以自动生成交换规则定义文件的大纲了,之所以叫大纲,是因为生成后的文件,还需要进一步配置,比如对需要翻译的字段配置参照档案等。 首先是设置一些生成参数,以决定是否重新生成,生成通用的规则定义文件,还是针对特定外部系统生成等,如下图所示

1.3、生成校验规则
可去除一些无需的字段,比如说主键、自定义项等。

新增接口时在此过程中点下一步会出现保存校验文件失败的错误提示,造成该问题的原因是未注册该接口的插件代理类,错误如图所示

解决方式:在home目录下pfxx\businessprocessor,找到对应模块的xml信息,本例模块为pmr,新增一条注册信息,如图。
[billtype]:第一步单据插件信息注册时的单据标识名称(本例为4D14)。
[classname]:新增的插件代理类名称
[classname]:单据元数据id(md_class表中的id字段)
[name]:单据节点名称

1.4、生成样本数据
配置好规则定义文件,就可以生成相应的样本数据,其数据格式符合当前的规则定义,可以直接发送到NC系统中。如果修改了规则定义文件,最好重新生成一下样本数据,以免样本数据和规则定义不相符。
根据规则定义生成样本数据,对于外系统没有明确数据格式的情况下,生成的样本数据可以作为外系统生成数据的模板;如果外系统已经有了具体的数据格式,只需要对比一下外系统的数据格式与生成的样本是否一致,便可检验规则定义正确与否。
此界面右上方有一保存按钮,可以保存生成的样本数据到本地硬盘。

1.5、辅助信息项设置
利用交换平台做数据交互时,业务数据一般都放在具体的XML文档中,但是,发送过程中往往还有一些数据,并不需要也不能写到每个具体的XML文档里,这些数据,用户往往需要根据当前的发送方、接受方、单据类型及具体的业务场景进行设定,比如说发送凭证时,针对凭证表头表体的控制参数是根据不同的发送方、接受方、及凭证类别由用户灵活控制的;另外如存货基础档案发送到集团时,用户也需要配置,档案可以分配到那些公司。诸如此类的信息,在交换平台中称之为辅助信息。
辅助信息分设计态和运行态,设计态是指从程序开发的角度,交换平台提供了一个类似数据池的数据存贮区,插件开发人员先定义当前单据所需要的辅助信息项目,比如上面所说的凭证控制信息、存货的分配公司等,插件开发人员定义好这些项目之后,在[集成平台]-[数据交换管理]-[信息交换平台]-[辅助信息设置]界面,用户就可以在运行态时配置这些项目的值,最终在业务插件类里,用户配置好的这些值被交给插件使用。简单的说就是插件开发人员借助信息交换平台辅助信息这个数据池,存放一些特定的项目,在运行态时收集用户的设置,最终在插件处理这些用户的设置信息。

1.5、配置文件导出
到此步骤后,开发配置功能已全部完成,这个时候需要将配置文件内容导出至本地,然后需放入测试环境和生产环境下。

2、手动加载界面
从[集成平台]-[数据交换管理]-[集成工具开发]-[手动加载界面],打开手动加载界面选择刚保存的样本数据发送xml测试。
2.1、参数修改:
【account】:
与手动加载界面中目标url地址中的account参数保持一致,本地开发环境一般为develop。
【sender】:
与外部系统信息设置节点中自动生成的外部系统编码保持一致,本例为default。其余信息可在前台节点新增一条数据后按照数据库内容对比修改
示例XML代码:
<?xml version="1.0" encoding='UTF-8'?>
<ufinterface account="99" billtype="4D14" filename="" groupcode="" isexchange="Y" replace="Y" roottag="" sender="RL">
<bill id="">
<billhead>
<!--项目组织,最大长度为20,类型为:String-->
<pk_org>03</pk_org>
<!--项目组织,最大长度为20,类型为:String-->
<pk_org_v>03</pk_org_v>
<!--项目,最大长度为20,类型为:String-->
<pk_project>D-2012-B-02</pk_project>
<!--集团,最大长度为20,类型为:String-->
<pk_group>001</pk_group>
<!--需求单号,最大长度为40,类型为:String-->
<bill_code></bill_code>
<!--单据状态,最大长度为0,类型为:Integer-->
<bill_status>-1</bill_status>
<!--备注,最大长度为200,类型为:String-->
<memo>测试备注</memo>
<!--需求编制人,最大长度为20,类型为:String-->
<pk_req_maker></pk_req_maker>
<!--需求编制部门,最大长度为20,类型为:String-->
<pk_req_dept></pk_req_dept>
<!--需求编制日期,最大长度为19,类型为:UFDate-->
<req_make_date>2023-12-23 13:00:00</req_make_date>
<!--单据类型,最大长度为4,类型为:String-->
<bill_type>4D14</bill_type>
<!--制单人,最大长度为20,类型为:String-->
<billmaker>nc001</billmaker>
<!--制单日期,最大长度为19,类型为:UFDate-->
<billmaketime>2023-12-23 13:00:00</billmaketime>
<!--创建人,最大长度为20,类型为:String-->
<creator>nc001</creator>
<!--创建时间,最大长度为19,类型为:UFDateTime-->
<creationtime>2023-12-23 13:00:00</creationtime>
<!--交易类型,最大长度为20,类型为:String-->
<pk_transitype>0001A21000000000PG08</pk_transitype>
<!--交易类型编码,最大长度为30,类型为:String-->
<transi_type>4D14-01</transi_type>
<bodyvos>
<item>
<!--行号,最大长度为30,类型为:String-->
<rowno>10</rowno>
<!--项目组织,最大长度为20,类型为:String-->
<pk_org>03</pk_org>
<!--项目组织,最大长度为20,类型为:String-->
<pk_org_v>03</pk_org_v>
<!--集团,最大长度为20,类型为:String-->
<pk_group>001</pk_group>
<!--物料,最大长度为20,类型为:String-->
<pk_material>030101002</pk_material>
<!--单位,最大长度为20,类型为:String-->
<pk_measdoc>TNE</pk_measdoc>
<!--CBS,最大长度为20,类型为:String-->
<pk_cbs_node>0101</pk_cbs_node>
<!--库存组织,最大长度为20,类型为:String-->
<pk_stockorg>03</pk_stockorg>
<!--物料,最大长度为20,类型为:String-->
<pk_material_v>030101002</pk_material_v>
<!--数量,最大长度为28,类型为:UFDouble-->
<nnum>10.00</nnum>
<!--需求日期,最大长度为19,类型为:UFDate-->
<require_date>2023-12-23 13:00:00</require_date>
<!--备注,最大长度为200,类型为:String-->
<memo>测试明细备注</memo>
<!--项目,最大长度为20,类型为:String-->
<pk_project>D-2012-B-02</pk_project>
<!--库存组织,最大长度为20,类型为:String-->
<pk_stockorg_v>03</pk_stockorg_v>
<!--服务价格系数,最大长度为28,类型为:UFDouble-->
<service_prc_ratio></service_prc_ratio>
</item>
</bodyvos>
<!--币种,最大长度为20,类型为:String-->
<pk_currtype>CNY</pk_currtype>
<!--是否为最新版本,最大长度为1,类型为:UFBoolean-->
<last_v_flag>Y</last_v_flag>
<!--当前版本,最大长度为28,类型为:UFDouble-->
<contr_version>1.00000000</contr_version>
<!--需求编制部门,最大长度为20,类型为:String-->
<pk_req_dept_v></pk_req_dept_v>
<!--业务类型,最大长度为20,类型为:String-->
<busi_type>Cxx-RQHT-01</busi_type>
</billhead>
</bill>
</ufinterface>
2.2、 外部系统信息设置

3、常见问题处理
3.1、xml转换为ncvo时出错

问题原因:
插件注册xml内关联元数据id不正确(相关表:md_class元数据)或xml封装值不对

3.2、保存vo数据失败

问题原因:
xml中的<bill id="">标签中的id值重复生成,修改id值即可

3.3、无法初始化插件类

问题原因:
插件开发向导注册接口时,插件类名称输入有误,应为新开发的插件类路径而非功能注册处的功能插件类。

3.4、按编码方式翻译出错(常见)

问题原因:
校验文件管理处未设置自定义翻译器,或翻译器选择的不对。

3.5、校验文件管理内无法打开新注册接口单据类型的xml模板

问题原因:
数据库xi_billdefine表内aamlevel字段值不正确,新增接口默认值为-1,校验文件管理获取xml文件是是获取aamlevel为0的,修改值即可获取。

3.6、单据已被他人修改,请重新查询
问题原因:
xml内ts相关字段与数据库内时间戳不一致(来源单据ts,ts之类的)。
3.7、成套件接口执行修改时不生效
解决方式:
修改前增加vo转换步骤。

3.8、fail to save VO Array ~#@
问题原因:
存在必输的字段没放值。

1519

被折叠的 条评论
为什么被折叠?



