寄售结算单及视图编程模型接口简介原创
金蝶云社区-文安根
文安根
5人赞赏了该文章 671次浏览 未经作者许可,禁止转载编辑于2023年11月02日 17:53:34

    金蝶云星空供应链领域销售模块下的寄售结算单在2021.10月版本之前一直有几个缺陷,例如1,不支持在直接调拨单中通过WebApi下推生成寄售结算单;2,多张直接调拨单或单张直接调拨单多个分录下推生成寄售结算单被分组成多张下游单据时,在下游批量生成的界面中不做任何处理直接点‘生成全部’时会报错,必须每张单据都点一下才能生成全部单据;3,客户通过批量导入只有结算明细无选单明细的寄售结算单(导入时只能先暂存),必须要寄售结算单一个单据一个单据点开后,在寄售结算单编辑界面再手动点自动匹配发货才能完成寄售流程,这对批量导入暂存的寄售结算单据或手工暂存的量非常大的寄售结算单的客户来说,自动匹配发货就非常耗时。很多客户都遇到这些问题,通版也计划在2021.11月左右优化这些问题;4,如果在直接调拨单审核操作上挂了自动下推寄售结算单的服务,会提示结算明细物料为空的校验信息导致下推失败。这么多缺陷,究其原因,主要是因为寄售结算单比较特殊和复杂,很多计算逻辑放在表单插件方法中(这些逻辑无法放到后端服务或下推插件中,因为计算复杂且要即时显示匹配结果到界面给客户看),然而通过WebApi下推或分组下推后未一个一个地点击单据,这些表单插件方法很多就会不调用,最终导致报错或不支持。文章后面将简单介绍如何实现在未打开单据的前提下以实例化BOS底层‘动态表单视图模型编程接口’(参看程序集Kingdee.BOS.Core.dll中的接口定义Kingdee.BOS.Core.DynamicForm.IDynamicFormViewServiceKingdee.BOS.Core.DynamicForm.IDynamicFormView)的方式调用表单插件逻辑以解决上面的缺陷问题,下面先简单介绍下寄售结算单各单据体,子单据体之间的关系及相关操作(以下信息是以2021.11月版本为准介绍的)然后再描述下‘动态表单视图模型编程接口IDynamicFormView’及‘动态表单内部使用的接口IDynamicFormViewService’(根据BOS底层的描述,所有的BOS视图模型最终都由这两个接口承载,通过反编译这两个接口可以看到这两个接口提供了表单单据插件中的很多方法的调用入口)。

    寄售结算单承载上下游数据是通过选单明细页签数据实现的(一些客户二开寄售结算单且用结算明细来承载上下游关系是不正确的,不管是直接调拨单下推寄售结算单,还是寄售结算单下推销售出库单/销售退货单,或者寄售结算单下推应收单,可以看到单据转换中的字段映射都是依托寄售结算单中的选单明细字段的),但通常客户一般是只录入结算明细页签数据,然后再点击‘自动匹配发货’按钮,通过自动匹配发货功能会生成选单明细数据, 如下图1-1所示:

image.png

图1-1

    

    这里的‘自动匹配发货'是以结算明细页签中录的物料,仓库,仓位,计价单位,是否赠品等字段和单据头上的客户,组织,币别等字段维度从直接调拨单(业务类型为寄售)中按直接调拨单单据内码,单据时间,单据分录内码升序排序查找匹配,然后通过寄售结算单中的结算明细中的数量计算要匹配哪些直接调拨单,最终调用BOS平台的下拉(Kingdee.BOS.Contracts.IConvertService.Draw)操作完成类似选单操作以达到自动匹配发货功能(Draw方法之后选单明细就有数据了)。针对前面的自动匹配发货功能,1,如果多条结算明细物料,仓库,仓位都相同,可能只是结算单价不同,且它们的数量比较小,那么多条结算明细就可能匹配到同一条直接调拨单分录(这个调拨单分录数量比较大),这个时候选单明细中匹配到的数据就要按结算明细中的数量拆分成多行。2,如果结算明细数量比较大,而直接调拨单分录数量比较小(它们的维度相同),这样就可能存在一个结算明细匹配到多个直接调拨单分录。从上面的1,2点可以看到结算明细选单明细是多对多的,一个结算明细记录是可能对应多个选单明细记录,而一个选单明细记录也可能对应多个结算明细记录。它们之间的这种关系是通过子单据体匹配发货’(匹配发货是结算明细的子单据体)中的FRowId体现的。一个结算明细记录对应一个或多个匹配发货,每个匹配发货通过自身FRowId关联选单明细(选单明细中也有FRowId字段,FRowId相同的匹配发货和选单明细就是一次关联)。

    如果是从直接调拨单下推寄售结算单(不分组的情况下)或者从寄售结算单选单直接调拨单,这种情况也是BOS通过单据转换中的配置信息生成下游寄售结算单中的选单明细信息,此时寄售结算单中的结算明细还是一个空的单据体,在寄售结算单表单插件中的AfterBindData方法中,有会比较复杂的逻辑实现根据选单明细生成结算明细。这种情况下一般是一个选单明细对应一个结算明细

    2021.11版本,将实现批量匹配功能,就是在寄售结算单列表中有一个‘自动匹配发货’按钮,选中一些单据后,点击此按钮在不打开单据的情况下实现批量匹配发货(由于此处为批量自动匹配发货,因此会比较慢,建议每次不要选太多条寄售结算单自动匹配发货)。如文章开头所述,如果在列表中不打开单据就想实现此功能,那么表单插件很多代码就不调用,表单插件不调用就动态生成不了结算明细或选单明细数据导致后续的保存操作报错。这个时候就用到了后台服务调用表单插件的功能了或者列表插件调用表单插件的功能,其实这个功能最终还是依托BOS平台底层的IDynamicFormViewService接口中公开的方法。  

    通过反编译寄售结算单的列表插件类‘Kingdee.K3.SCM.Sal.Business.PlugIn.ConsignmentSettleList’(在程序集Kingdee.K3.SCM.Sal.Business.PlugIn.dll),可以看到类中有SimulateAutoMatch()方法,此方法调用的OpenWebView()方法为最核心方法,传入单据元数据和表单主码就能生成一个ImportBillView对象,将此对象强制转换成IBillViewServie接口(IBillViewServie实现了IDynamicFormViewService),就可以调用此接口的MainBarItemClick("tbAutomaticMatch")方法,传入的参数就是表单中的菜单Key,这样就相当于在列表上模拟了寄售结算单据上的菜单操作,而这个菜单的操作能够修改或生成寄售结算单据的选单明细数据包,最后再调用BOS平台提供的保存操作。当然如果反编译寄售结算单保存操作上挂的服务端操作类'Kingdee.K3.SCM.App.Sal.ServicePlugIn.ConsignSettle.Save'(在程序集Kingdee.K3.SCM.App.Sal.ServicePlugIn.dll),也能够看到类似的方法,这主要是因为这个Save操作要兼容WebApi生成单据和批量下推被分组的情况,这两种情况可没有像列表插件那样有一个列表插件,它们是直接走Save后端服务操作插件。核心代码如下图1-1及图1-2所示:

image.png

图1-1


image.png

图1-2


    最后,附上BOS平台视图编程模型接口的反编译后的继承关系图,如下图2-1左侧树形图所示:

image.png

图2-1


它们之间的关系用代码表现为如下所示:

public class ImportBillView : BillView, IImportView 
public partial class BillView : DynamicWebFormView, IBillView, IBillViewService 
public interface IBillViewService : IDynamicFormViewService, IDisposable 
public interface IBillView : IDynamicFormView 
public partial class DynamicWebFormView : AbstractDynamicWebFormView, IDynamicFormViewService  
public partial class AbstractDynamicWebFormView : IDynamicFormView

从上面反编译可以看出,IDynamicFormView 和 IDynamicFormViewService共同完成BOS视图模型的最底层抽象。通过层层继承和扩展。最终由BillView呈现单据视图,由ImportBillView呈现引入视图。寄售结算单正是通过ImportBillView实现模拟了单据视图且调用了单据视图中的插件方法,这样就能达到不打开单据就能调用单据插件方法,客户二开时也可以利用此方法实现类似功能。从上面的View层间的继承关系(单据视图继承于动态表单视图)可以推导出插件的继承关系,表单插件抽象基类AbstractBillPlugIn 继承于动态表单插件抽象基类AbstractDynamicFormPlugIn



赞 5