本文描述了在某业务单据上实现弹性域字段自动赋值的过程。首先概述了需求背景,即点击单据工具栏按钮后,系统自动创建单据数据并给弹性域字段赋值。随后,文章详细说明了实现该功能的思路、方案、具体实现步骤,包括在系统中新建单据、维护辅助属性定义和物料数据、后台编码实现等。实现过程中,通过查询辅助属性、获取单据实体类型及弹性域字段属性,创建并赋值弹性域实体对象,最终创建单据并保存数据。展示了效果图,并提醒了开发环境版本要求及注意事项,如维护物料数据后需更新插件中的全局变量,弹性域字段赋值前需先给其绑定的基础资料字段赋值等。同时提供了参考资料以便进一步学习。
关键词:弹性域
一、需求
某业务单据上包含一弹性域字段。点击该单据上工具栏的按钮后,系统自动在后台创建一条单据数据,并给弹性域字段赋值。
二、思路与方案
弹性域字段是苍穹里面很复杂的控件之一,如涉及该控件的二次开发,请一定要先弄清弹性域字段数据的底层存储关系,可参考 关于苍穹弹性域字段开发的样例(一) 。
三、实现过程
1. 新建单据,其单据设计器界面如下图所示。
单据设计器
2. 在 【系统服务云】—【基础资料】—【供应链数据】—【辅助属性定义】中维护 2 个辅助属性定义。
3. 在【系统服务云】—【基础资料】—【主数据】—【物料】中维护 1 条物料数据,然后在“公共信息”中开启“启用辅助属性”,并新增两个辅助属性,分别选择上一步添加的辅助属性定义。
4. 在后台创建一条单据数据并给弹性域字段赋值。
/** * 在后台创建一条单据数据并给弹性域字段赋值 */ private void newAndSaveFlexFieldVal() { // 查询基础资料-物料数据所启用的辅助属性 List<Long> flexPropertyIds = FlexService.getBaseUseFlexProperties(KEY_BASEDATAENTITYNUM, VAL_BASEDATA, "auxpty"); // 获取待新建单据的单据实体类型 MainEntityType entityType = EntityMetadataCache.getDataEntityType(KEY_BILLNUMBER); // 根据单据实体类型获取其中弹性域字段的属性对象 FlexProp flexFieldProperty = (FlexProp) entityType.findProperty(KEY_FLEXFIELD); int flexTypeId = flexFieldProperty.getFlexTypeId(); // 获取弹性域实体类型 FlexEntityType flexFieldEntityType = FlexEntityMetaUtils.getBasedataPropFlexEntityType(KEY_BILLNUMBER, KEY_FLEXFIELD, flexTypeId, flexPropertyIds); // 创建一个弹性域实体对象 DynamicObject flexFieldVal = new DynamicObject(flexFieldEntityType); DataEntityPropertyCollection properties = flexFieldEntityType.getProperties(); // 设置初始值 for (IDataEntityProperty prop : properties) { String key = prop.getName(); if ("id".equals(key)) { continue; } if (!(prop instanceof BasedataProp)) { if (key.endsWith("_id")) { // 可不设置 // prop.setValue(flexFieldVal, VAL_FLEX1_BASEDATA); continue; } String subKey = key; key = subKey.split("__")[1]; switch (key) { case "f000002": prop.setValue(flexFieldVal, VAL_FLEX1_TXT); break; default: break; } } else { prop.setValue(flexFieldVal, BusinessDataServiceHelper.loadSingle(VAL_FLEX2_BASEDATA, "bos_user")); } } // 将新创建的弹性域实体对象封装成可赋值给单据上弹性域字段数据的格式 FlexEntireData flexEntireData = new FlexEntireData(); flexEntireData.setFlexData(flexFieldEntityType, flexFieldVal); long id = FlexService.saveFlexData(flexFieldEntityType, flexEntireData); DynamicObject flexObject = (DynamicObject) flexFieldProperty.getComplexType().createInstance(); flexObject.set("id", id); Map<String, Object> values = flexEntireData.getFlexValue(); flexObject.set("value", SerializationUtils.toJsonString(values)); // 创建单据数据,并给各字段赋值(含基础资料 & 弹性域字段) DynamicObject demobillorgObj = BusinessDataServiceHelper.newDynamicObject(KEY_BILLNUMBER); demobillorgObj.set("billno", "FlexFieldDemo2-001"); demobillorgObj.set(KEY_BASEDATAFIELD, BusinessDataServiceHelper.loadSingle(VAL_BASEDATA, KEY_BASEDATAENTITYNUM)); demobillorgObj.set(KEY_FLEXFIELD, flexObject); demobillorgObj.set("billstatus", "A"); demobillorgObj.set("org", "100000"); OperationResult result = SaveServiceHelper.saveOperate(KEY_BILLNUMBER, new DynamicObject[] { demobillorgObj }, OperateOption.create()); logger.info("result: " + result.getSuccessPkIds()); }
四、效果图
点击单据新增界面上的“测试按钮”后,系统自动在后台创建一条单据数据并给弹性域字段赋值,同时退出新增界面。然后,点击单据编码进入单据详情界面,即可看到弹性域字段及其关联的基础资料字段都成功赋值。
五、开发环境版本
V2.0.039.57(含)以上
六、注意事项
1. 维护一条物料数据后,需将其主键ID更新至插件中的全局变量 VAL_BASEDATA 。
2. 如需给弹性域字段赋默认值,需先给其绑定的基础资料字段赋值。参考资料 关于苍穹弹性域字段开发的样例(一) 中已介绍,弹性域字段需通过其“基础资料字段”属性与某个基础资料相关联。
七、参考资料
弹性域字段后台赋值.zip(9.16KB)
推荐阅读