**摘要**:本文介绍了在botp环境下,根据复杂条件(如物料类型)将上游单据的分录拆分成多个下游单据分录的实现过程。包括配置转换规则、编写转换插件`ReqConverToOderPlugin`,在`afterFieldMapping`事件中处理拆单逻辑,根据物料分组信息将相同类型的物料拆分到同一个采购订单上,并通过动态调整分录数据源来实现。
一、需求背景
在botp下推上游单据生成下游单据的时候,根据需要根据一些条件把某个分录的数据拆分成多个单据的分录。
①对于简单条件:根据分录上某个字段的值进行分单,可以通过配置转换规则中的分单合并的分单策略指定分单依据的字段(参考
https://club.kdcloud.com/article/215470693172078336)
②对于动态条件:根据特定条件动态指定分录上某个字段的值进行分单,可以通过转换规则插件在beforeBuildGroupMode分单前事件中动态动态调整分单、合并依赖的字段(参考https://dev.kingdee.com/index/docsNew/5f24ec57-58fa-48a5-a205-c07d270b9514)
③复杂条件拆单:例如,根据上游单据分录上关联的第三个表单数据对分录行数据进行拆分。采购申请单下推生成采购订单的时候,需要根据采购申请单的采购分录上物料字段是否是同一个类型(分类)的物料,拆分生成同一个单据的一个采购订单分录上。(实际上,该业务场景下只需要在转换规则的分单策略中设置“按规则分组合并生成”,并且添加物料的分组编码就可以实现,也就是第①中情况;这里只是为了说明自行业务拆单的实现逻辑)
本文主要介绍第③种业务拆单的实现过程。
二、实现方案
配置好转换规则,下推采购申请单,在目标单赋值完之后afterFieldMapping事件中把采购申请单相同类型的物料拆分到同一个采购订单上。
1、配置转换规则
2、实现逻辑
编写转换插件ReqConverToOderPlugin,继承基类
kd.bos.entity.botp.plugin.AbstractConvertPlugIn,重写方法afterFieldMapping
public class ReqConverToOderPlugin extends AbstractConvertPlugIn { // 目标单赋值后 @Override public void afterFieldMapping(AfterFieldMappingEventArgs e) { ExtendedDataEntitySet targetExtDataEntitySet = e.getTargetExtDataEntitySet(); ExtendedDataEntity[] findByEntities = targetExtDataEntitySet.FindByEntityKey("sunp_order_demo"); for (ExtendedDataEntity extendedDataEntity : findByEntities) { // 拆分后的扩展单据数据 List<ExtendedDataEntity> extendedDataEntities = Lists.newArrayList(); // 物料id ArrayList<String> materierIds = new ArrayList<>(); // 物料id对应的分组id HashMap<String, String> materierGroupMap = new HashMap<>(); //转换规程下推生成的采购订单 DynamicObject dataEntity = extendedDataEntity.getDataEntity(); //用来遍历分录的拆单数据源 DynamicObject splitObj = (DynamicObject) new CloneUtils(false, true).clone(dataEntity); // sunp_ordentryentity采购订单单据体 DynamicObjectCollection ordEntryentities = splitObj.getDynamicObjectCollection("sunp_ordentryentity"); for (DynamicObject ordEntry : ordEntryentities) { DynamicObject materier = ordEntry.getDynamicObject("sunp_materierfield"); // 把物料id添加到list上,最后查一次查数据库 materierIds.add(materier.getString("id")); } // 获取物料的分组信息 DynamicObjectCollection materierInfos = QueryServiceHelper.query("bd_material", "id,group", new QFilter[] { new QFilter("id", QCP.in, materierIds) }); for (DynamicObject materierInfo : materierInfos) { materierGroupMap.put(materierInfo.getString("id"), materierInfo.getString("group")); } DynamicObjectCollection orginCol = dataEntity.getDynamicObjectCollection("sunp_ordentryentity"); orginCol.clear(); // 一个物料分组对应的下游单据 HashMap<String, DynamicObject> groupOrderMap = new HashMap<>(); for (DynamicObject ordEntry : ordEntryentities) { String materierId = ordEntry.getDynamicObject("sunp_materierfield").getString("id"); String groupId = materierGroupMap.get(materierId); if (!groupOrderMap.containsKey(groupId)) { if (groupId.equals(materierGroupMap.get(materierIds.get(0)))) { // 和第一行分录的物料相同分组的物料行拆分到原来botp下推生成的单据上 orginCol.add(ordEntry); } else {DynamicObject cloneObj = (DynamicObject) new CloneUtils(false, true).clone(splitObj); DynamicObjectCollection col = cloneObj.getDynamicObjectCollection("sunp_ordentryentity"); col.clear(); col.add(ordEntry); groupOrderMap.put(groupId, cloneObj); } } else { // 相同分组的物料分录拆分到同一个单据中 DynamicObject tempObj = groupOrderMap.get(groupId); tempObj.getDynamicObjectCollection("sunp_ordentryentity").add(ordEntry); } } int dataIndex = 0; for (DynamicObject cloneObj : groupOrderMap.values()) { extendedDataEntities.add(new ExtendedDataEntity(cloneObj, dataIndex++, 0)); } if (extendedDataEntities != null) { targetExtDataEntitySet.AddExtendedDataEntities("sunp_order_demo", extendedDataEntities); } } super.afterFieldMapping(e); } }
三、实现效果
采购申请单审核之后点击下推,生成两张采购订单,每一个订单分录上的物料属于同一类型(分类)的物料,如下图。
补充说明:以上拆单后生成的两个采购订单和采购申请单没有关联关系,无法进行反写、上查、下查,还需要手工修复它们的关联关系。参考:https://vip.kingdee.com/article/253169775340442880
ConverPlugin.zip(20.57KB)
sunp_testcloud-sunp_caseapp-20 …(11.37KB)
推荐阅读