审核自动下推生产、委外订单再自动提交审核原创
金蝶云社区-kaiming
kaiming
40人赞赏了该文章 652次浏览 未经作者许可,禁止转载编辑于2023年06月21日 10:16:45

客户场景:销售订单审核时自动下推生产订单,生产订单在保存操作插件上挂了个保存时自动提交审核的功能。手工点击生产订单保存能生效自动审核的效果,但是自动下推就会报错。

保存插件的自动提交审核案例参考:https://vip.kingdee.com/article/347812935806643968?channel_level=%E9%87%91%E8%9D%B6%E4%BA%91%E7%A4%BE%E5%8C%BA%7C%E6%90%9C%E7%B4%A2%7C%E7%BB%BC%E5%90%88&productLineId=1&isKnowledge=2


image.png

image.png

原因:生产订单的审核时会新开一个事务对生产订单明细行的状态转换做业务,程序中有地方需要用到生产订单的内码执行相关逻辑。按照上面的案例来说,提交和审核的方法放在了AfterExecuteOperationTransaction方法中,即保存事务结束了,审核时新开的那个事务就能够查询到单据内码,所以手工点击时功能正常。但是当给销售订单配置审核自动下推以后,销售订单审核变成了一个大事务,里面包着生产订单保存和生产订单状态机两个事务,大事务没提交会导致生产订单保存时生成的订单内码,状态机里读不到所以报错。

解决方法:把自动提交审核的代码从生产订单的保存下勾选取消掉,转移到上游单据审核插件的AfterExecuteOperationTransaction方法上(这里以销售订单为例子),因为自动下推会触发下游单据的保存,所以当上游单据审核完事务提交后的after方法中就能够查询到下游生产订单内码了,再去调用提交和审核操作。

代码案例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.ServiceHelper;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Kingdee.BOS.WebApi.Client;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Interaction;
using System.ComponentModel;

namespace 0000000
{
    [Kingdee.BOS.Util.HotUpdate]
    [Description("自动下推后提交审核")]
    public class 11111111111:AbstractOperationServicePlugIn
    {
        ///        
        /// 保存操作完毕,事务结束之后,进行自动提交、审核
        ///
        ///
        public override void AfterExecuteOperationTransaction(AfterExecuteOperationTransaction e)
        {
            string saveTime = "";
            DynamicObject[] dataEntitys = e.DataEntitys;
            for (int i = 0; i < dataEntitys.Length; i++)
            {
                DynamicObject dyObj = dataEntitys[i];
                if (this.OperationResult.IsSuccess && this.OperationResult.OperateResult != null && this.OperationResult.OperateResult.Count > 0)
                {
                    FormMetadata meta = MetaDataServiceHelper.Load(this.Context, "PRD_MO") as FormMetadata;
                    //通过查询当前销售订单分录内码和下游生产订单的link表找到下游的生产订单fid
                    string sql = string.Format(@"select 
                                                e.FID
                                                from T_SAL_ORDER	a
                                                left join T_SAL_ORDERENTRY	b on a.FID=b.FID
                                                left join T_PRD_MOENTRY_LK	c on c.FSBILLID=b.FID and c.FSID=b.FENTRYID
                                                left join T_PRD_MOENTRY		d on c.FENTRYID=d.FENTRYID
                                                left join T_PRD_MO			e on d.FID=e.FID
                                                where ISNULL(e.FID,0)<>0 and a.FID={0}
                                                group by e.FID", Convert.ToInt64(dyObj["Id"]));
                    DataTable Dt = DBServiceHelper.ExecuteDataSet(this.Context, sql).Tables[0];
                    List<object> ids=new List<object>();
                    if (Dt.Rows.Count > 0)
                    {
                        foreach (DataRow id in Dt.Rows)
                        {  
                            ids.Add(Convert.ToInt32(id["FID"].ToString()));
                        }

                        object[] idsObj = ids.ToArray<Object>();
                        // 设置提交参数
                        // using Kingdee.BOS.Orm;
                        OperateOption submitOption = OperateOption.Create();
                        submitOption.SetIgnoreWarning(this.Option.GetIgnoreWarning());
                        submitOption.SetInteractionFlag(this.Option.GetInteractionFlag());
                        submitOption.SetIgnoreInteractionFlag(this.Option.GetIgnoreInteractionFlag());
                        // 创建提交服务:using Kingdee.BOS.Contracts; using Kingdee.BOS.App;
                        ISubmitService submitService = ServiceFactory.GetSubmitService(this.Context);
                        IOperationResult submitResult = submitService.Submit(
                        this.Context, meta.BusinessInfo,
                        idsObj, "Submit", submitOption);
                        // 判断提交结果,如果失败,则内部会抛出错误,回滚代码
                        if (CheckOpResult(submitResult) == false)
                        {
                            return;
                        }
                        // 构建操作可选参数对象
                        OperateOption auditOption = OperateOption.Create();
                        auditOption.SetIgnoreWarning(this.Option.GetIgnoreWarning());
                        auditOption.SetInteractionFlag(this.Option.GetInteractionFlag());
                        auditOption.SetIgnoreInteractionFlag(this.Option.GetIgnoreInteractionFlag());
                        // 构建单据主键参数
                        List<KeyValuePair<object, object>> pkEntityIds = new List<KeyValuePair<object, object>>();
                        foreach (var pkValue in idsObj)
                        {
                            pkEntityIds.Add(new KeyValuePair<object, object>(pkValue, ""));
                        }
                        List<object> paras = new List<object>();
                        paras.Add("1");
                        paras.Add("");
                        // 调用审核操作
                        ISetStatusService setStatusService = ServiceFactory.GetSetStatusService(this.Context);
                        // 如下调用方式,需显示交互信息
                        IOperationResult auditResult = setStatusService.SetBillStatus(this.Context,
                        meta.BusinessInfo,
                        pkEntityIds,
                        paras,
                        "Audit",
                        auditOption);
                        // 判断审核结果,如果失败,则内部会抛出错误,回滚代码
                        if (CheckOpResult(auditResult) == false)
                        {
                            return;
                        }            
                            
                    }
                    
                }
            }
                //销售订单审核成功之后
            
                //// 取到需要自动提交、审核的单据内码
                //object[] pkArray = (from p in e.DataEntitys
                //                select p[0]).ToArray();
            
        }
        ///
        /// 判断操作结果是否成功,如果不成功,则直接抛错中断进程
        ///
        ///
        ///
        private bool CheckOpResult(IOperationResult opResult)
        {
            bool isSuccess = false;
            if (opResult.IsSuccess == true)
            {
                // 操作成功
                isSuccess = true;
            }
            else
            {
                if (opResult.InteractionContext != null
                && opResult.InteractionContext.Option.GetInteractionFlag().Count > 0)
                {// 有交互性提示
                    // 传出交互提示完整信息对象
                    this.OperationResult.InteractionContext = opResult.InteractionContext;
                    // 传出本次交互的标识,
                    // 用户在确认继续后,会重新进入操作;
                    // 将以此标识取本交互是否已经确认过,避免重复交互
                    this.OperationResult.Sponsor = opResult.Sponsor;
                    // 抛出错误,终止本次操作
                    throw new KDBusinessException("", "本次操作需要用户确认是否继续,暂时中断");
                }
                else
                {
                    // 操作失败,拼接失败原因,然后抛出中断
                    opResult.MergeValidateErrors();
                    if (opResult.OperateResult == null)
                    {// 未知原因导致提交失败
                        throw new KDBusinessException("", "未知原因导致自动提交、审核失败!");
                    }
                    else
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("自动提交、审核失败,失败原因:");
                        foreach (var operateResult in opResult.OperateResult)
                        {
                            sb.AppendLine(operateResult.Message);
                        }
                        throw new KDBusinessException("", sb.ToString());
                    }
                }
            }
            return isSuccess;
        }
    }

}

最后注册一下即可,委外订单处理逻辑也是如此

image.png

赞 40