通过模拟单据View加载单据&修改单据信息原创
金蝶云社区-程晓峰
程晓峰
16人赞赏了该文章 3515次浏览 未经作者许可,禁止转载编辑于2022年04月02日 14:23:09

需求背景:例如:

      销售订单已经审核,且下推了发货通知单和销售出库单,应收时候调整了价格,按最新价格进行了结算,随后销售订单通过变更方式,变更了销售订单的价格信息,此时希望同步变更更新下游发货通知单和销售出库单的价格,且需要联动更新税额、金额等相关运算(需要实现单据自身所有的联动运算)。

实现方式:

1.插件通过脚本直接更新对应字段值。(比较直接,但是局限在于不能达到界面录单时的字段联动公式逻辑和服务触发。可能会有数据缺陷,需要脚本考虑完善整个逻辑过程,较为复杂)

2.类似这种业务需求就需要在插件代码中需要通过代码模拟单据View加载单据和修改单据信息:

通过模拟View加载单据模式,可以利用单据的View和Model,就像界面操作修改单据一样,修改字段触发字段配置的公式逻辑。

  1. 构造模拟单据View,并加载单据

     FormMetadata meta = (FormMetadata)Kingdee.BOS.ServiceHelper.MetaDataServiceHelper.Load(this.Context, SCMFormIdConst.SAL_OUTSTOCK);//单据唯一标识

       public IDynamicFormView OpenWebView(Context ctx, FormMetadata meta, object pkid = null)

        {

                BusinessInfo info = meta.BusinessInfo;

                Form form = info.GetForm();

                BillOpenParameter param = new BillOpenParameter(SCMFormIdConst.SAL_OUTSTOCK, null);        

                param.SetCustomParameter("formID", form.Id);

                //根据主键是否为空 置为新增或修改状态

                param.SetCustomParameter("status", !IsPrimaryValueEmpty(PkId) ? "Edit" : "AddNew");

                param.SetCustomParameter("PlugIns", form.CreateFormPlugIns());  //插件实例模型

               //修改主业务组织无须用户确认

                param.SetCustomParameter("ShowConformDialogWhenChangeOrg", false); 

                param.Context = this.Context;

                param.FormMetaData = meta; 

                param.LayoutId = param.FormMetaData.GetLayoutInfo().Id;

                param.PkValue = !IsPrimaryValueEmpty(PkId) ? PkId: null;//单据主键内码FID

                param.Status= !IsPrimaryValueEmpty(PkId) ? OperationStatus.EDIT : OperationStatus.ADDNEW;


                IResourceServiceProvider provider = form.GetFormServiceProvider();

               //普通的动态表单模式DynamicFormView

               //IDynamicFormView billview  = provider.GetService(typeof(IDynamicFormView)) as IDynamicFormView;

              //这里模拟为引入模式的WebView,否则遇到交互的时候会有问题,移动端目前无法直接交互

              Type type = Type.GetType("Kingdee.BOS.Web.Import.ImportBillView,Kingdee.BOS.Web");

               IDynamicFormView billview  = (IDynamicFormView)Activator.CreateInstance(type);

                (billview  as IBillViewService).Initialize(param, provider);//初始化

                (billview  as IBillViewService).LoadData();//加载单据数据

                //如果是普通DynamicFormView时,LoadData的时候会加网控,要清除。//引入模式View不需要

               // (billview  as IBillView).CommitNetworkCtrl();

                 

               return billview  ;

     }

      private bool IsPrimaryValueEmpty(object pk)

        {

            return pk == null || pk.ToString() == "0" || string.IsNullOrWhiteSpace(pk.ToString());

        }


  2.触发单据相关字段更新赋值,并触发联动触发配置的值更新事件(相关配置公式和服务)

billview.Model.SetValue("FTaxPrice",row);//含税单价字段赋值,row为具体行号

billview.InvokeFieldUpdateService("FTaxPrice", row);//联动触发含税单价值更新事件,row为具体行号

 

 3.修改完单据需要调用保存操作

 方式1: //直接调用保存操作

    billview.InvokeFormOperation(Kingdee.BOS.Core.DynamicForm.FormOperationEnum.Save);

 方式2:  //通过保存数据包模式,可以得到保存操作结果

DynamicObject saveResult=BOS.ServiceHelper.BusinessDataServiceHelper.Save(this.Context, billview.Model.DataObject); 


4.拓展知识:

IBusinessFlowTrackerService 有自己的保存、审核等方法,仅只是业务流程跟踪、执行反写相关逻辑

以上仅只是修改、保存了单据数据 如果单据有上游关联关系,需要通过IBusinessFlowTrackerService 同步流程数据,执行触发以下(审核)相关的反写规则 

//客户端得到IBusinessFlowTrackerService 服务对象,通过接口获取

//IBusinessFlowTrackerService flowTracker = Kingdee.BOS.Contracts.ServiceFactory.GetBusinessFlowTrackerService(this.Context);

 //服务端获取IBusinessFlowTrackerService 服务对象,通过BOS.App.ServiceHelper获取

     IBusinessFlowTrackerService flowTracker = Kingdee.BOS.App.ServiceHelper.GetService<IBusinessFlowTrackerService>();

//调用流程跟踪对象的 审核,不是真正的审核单据,仅只是触发审核相关业务流程和反写而已

    flowTracker.Audit(this.Context, new DynamicObject[] { billview.Model.DataObject }, billview.Model.BusinessInfo, OperateOption.Create());


 5. 注意事项:

     如果启用了信用管理,那么修改单据(单价、数量)影响了金额时,需要进行信用重算。    

     如果是库存单据,那么修改单据(数量联动库存数量)时,需要进行即时库存校对。  

                                   

赞 16