当前位置: 首页 > 编程日记 > 正文

单据自动转换并审核的方法示例

需求要点:在单据A的界面点击“自动转换”,则自动产生审核态的单据B;若单据B不满足审核条件,则维持“提交”态;若单据B不满足保存校验,则维持“暂存”态;若转换失败,给出界面提示。

实现思路:
1.通过转换规则来定义单据A到单据B的转换关系,便于扩展,也便于使用已有的插件和服务;
2.定义一个空操作“自动转换”,扩展AbstractOperationServicePlugIn,重写EndOperationTransaction方法,方便处理事务;
3.依次调用单据转换服务、暂存服务、保存服务、提交服务和审核服务,以保证当前服务失败时能维持前一服务的状态;
4.根据上述服务调用的结果构造“自动转换”的操作结果;
5.若需求变更,只能生成审核态的单据B,否则不予生成,就要调用删除服务将所有审核不通过的单据删除,再构造操作结果;也可以直接抛出异常throw new KDBusinessException("", string.Join("\n", innerResult.ValidationErrors.Select(o => o.Message)))。

代码示例:

    public override void EndOperationTransaction(BOS.Core.DynamicForm.PlugIn.Args.EndOperationTransactionArgs e){base.EndOperationTransaction(e);// 转换 //ConvertRuleElement ruleElement = AppServiceContext.ConvertService.GetConvertRules(this.Context, "srcFormId", "destFormId").Where(o => o.IsDefault == true).FirstOrDefault();ListSelectedRowCollection rows = new ListSelectedRowCollection();int i = 0;foreach (var srcData in e.DataEntitys){ListSelectedRow row = new ListSelectedRow(srcData.GetDynamicObjectItemValue<string>("Id"), string.Empty, i++,"srcFormId");rows.Add(row);}OperateOption option = OperateOption.Create();option.SetVariableValue(BOSConst.CST_ConvertValidatePermission, true);PushArgs pushArgs = new PushArgs(ruleElement, rows.ToArray());// 转换生成目标单ConvertOperationResult convResult = AppServiceContext.ConvertService.Push(this.Context, pushArgs, option);DynamicObject[] destObjs = convResult.TargetDataEntities.Select(r => r.DataEntity).ToArray();// 目标单元数据FormMetadata destFormMetadata = AppMetadataContext.LoadWithNoVerCheck(this.Context, "destFormId") as FormMetadata;// 操作选项option = OperateOption.Create();option.SetIgnoreWarning(false);// 上一步操作成功的目标单List<object> lastSuccessIdLst = new List<object>();// 本操作成功的目标单List<object> successIdLst = new List<object>();// 操作失败的目标单List<DynamicObject> failedobjs = new List<DynamicObject>();// 操作结果IOperationResult result = new OperationResult();// 错误信息List<ValidationErrorInfo> errorLst = new List<ValidationErrorInfo>();// 暂存 //IDraftService service = Kingdee.BOS.Contracts.ServiceFactory.GetService<IDraftService>(this.Context);IOperationResult innerResult = service.Draft(this.Context, destFormMetadata.BusinessInfo, destObjs);// 暂存成功的目标单successIdLst = innerResult.OperateResult.Select(o => o.PKValue).Distinct().ToList();// 暂存不通过的目标单failedobjs = destObjs.Where(o => !successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToList();if (failedobjs != null && !failedobjs.IsEmpty()){errorLst.Add(new ValidationErrorInfo("", "Id", 0, 0, "DraftError", string.Format("{0}暂存失败:{1}",string.Join(",", failedobjs.Select(o => o.GetDynamicObjectItemValue<string>("BillNo"))), string.Join("\n", innerResult.ValidationErrors.Select(o => o.Message))), "", ErrorLevel.Error));}// 暂存不通过,则操作失败if (successIdLst.IsEmpty()){result.IsSuccess = false;}e.DataEntitys = e.DataEntitys.Where(o => successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToArray();// 保存 //if (!successIdLst.IsEmpty()){lastSuccessIdLst = successIdLst;innerResult = AppServiceContext.SaveService.Save(this.Context, destFormMetadata.BusinessInfo, destObjs.Where(o => successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToArray(), option);// 保存成功的目标单successIdLst = innerResult.OperateResult.Select(o => o.PKValue).Distinct().ToList();// 校验不通过的目标单failedobjs = destObjs.Where(o => lastSuccessIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))&& !successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToList();if (failedobjs != null && !failedobjs.IsEmpty()){errorLst.Add(new ValidationErrorInfo("", "Id", 0, 0, "SaveError", string.Format("{0}保存失败,已暂存:{1}",string.Join(",", failedobjs.Select(o => o.GetDynamicObjectItemValue<string>("BillNo"))), string.Join("\n", innerResult.ValidationErrors.Select(o => o.Message))), "", ErrorLevel.Error));}}// 提交 //if (!successIdLst.IsEmpty()){lastSuccessIdLst = successIdLst;innerResult = AppServiceContext.SubmitService.Submit(this.Context, destFormMetadata.BusinessInfo, successIdLst.ToArray(), "Submit", option);// 提交成功的目标单successIdLst = innerResult.OperateResult.Select(o => o.PKValue).Distinct().ToList();// 校验不通过的目标单failedobjs = destObjs.Where(o => lastSuccessIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))&& !successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToList();if (failedobjs != null && !failedobjs.IsEmpty()){errorLst.Add(new ValidationErrorInfo("", "Id", 0, 0, "SubmitError", string.Format("{0}提交失败,已保存:{1}",string.Join(",", failedobjs.Select(o => o.GetDynamicObjectItemValue<string>("BillNo"))), string.Join("\n", innerResult.ValidationErrors.Select(o => o.Message))), "", ErrorLevel.Error));}}// 审核 //if (!successIdLst.IsEmpty()){lastSuccessIdLst = successIdLst;List<KeyValuePair<object, object>> pkIds = new List<KeyValuePair<object, object>>();foreach (var o in successIdLst){pkIds.Add(new KeyValuePair<object, object>(o, ""));}//审核List<object> paraAudit = new List<object>();//1审核通过paraAudit.Add("1");//审核意见paraAudit.Add("");innerResult = AppServiceContext.SetStatusService.SetBillStatus(this.Context, destFormMetadata.BusinessInfo, pkIds, paraAudit, "Audit", option);// 审核成功的目标单successIdLst = innerResult.OperateResult.Select(o => o.PKValue).Distinct().ToList();// 审核不通过的目标单failedobjs = destObjs.Where(o => lastSuccessIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))&& !successIdLst.Contains(o.GetDynamicObjectItemValue<object>("Id"))).ToList();if (failedobjs != null && !failedobjs.IsEmpty()){errorLst.Add(new ValidationErrorInfo("", "Id", 0, 0, "AuditError", string.Format("{0}审核失败,已提交:{1}",string.Join(",", failedobjs.Select(o => o.GetDynamicObjectItemValue<string>("BillNo"))), string.Join("\n", innerResult.ValidationErrors.Select(o => o.Message))), "", ErrorLevel.Error));}}// 构造错误信息 //if (!errorLst.IsNullOrEmpty()){result.ValidationErrors.AddRange(errorLst);}// 将操作结果合并到空操作结果中this.OperationResult.IsSuccess = result.IsSuccess;if (!this.OperationResult.IsSuccess){this.OperationResult.ValidationErrors.Add(new ValidationErrorInfo("", "Id", 0, 0, "Error", string.Format("自动转换失败"), "", ErrorLevel.Error));}this.OperationResult.MergeResult(result);}

引用:

引用常用dll.jpg

转载于:https://www.cnblogs.com/fyq891014/p/8698041.html

相关文章:

优化 Web 服务器计算机和特定应用程序的配置文件以符合您的特定需要

默认情况下&#xff0c;ASP.NET 配置被设置成启用最广泛的功能并尽量适应最常见的方案。因此&#xff0c;应用程序开发人员可以根据应用程序所使用的功能&#xff0c;优化和更改其中的某些配置&#xff0c;以提高应用程序的性能。下面的列表是您应该考虑的一些选项。 仅对需要的…

3年编程经验无名校背景,全栈小哥是如何拿下Twitter Offer的?

作者 | zhiachong责编 | Aholiab头图 | CSDN 下载自视觉中国出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;外国小哥zhia是个有面试绝技的人&#xff0c;他只有三年的编程经验&#xff0c;并且没有任何名牌大学的光环&#xff0c;两年多以前&#xff0c;他同时获得…

Sco Unixware 7.1.3企业版服务器安装视频教程

Sco Unixware 7.1.3企业版服务器安装视频教程 UnixWare 7.1.3是最先进的工业标准Intel和AMD处理器系统运行平台。UnixWare 7.1.3是关键业务解决方案的可靠基础&#xff0c;具备可伸缩性、可靠性、安全性突出和物美价廉的特点。其中UnixWare 7.1.3企业版为中高端数据库服务器及应…

牛!Python 也能实现图像姿态识别溺水行为了!

作者 | 李秋键责编 | Carol封图 | CSDN 下载自视觉中国众所周知随着人工智能智能的发展&#xff0c;人工智能的落地项目也在变得越来越多&#xff0c;尤其是计算机视觉方面。所以今天我们也是做一个计算机视觉方面的训练&#xff0c;用python来判断用户溺水行为&#xff0c;结合…

Asp.net中多项目共享Session

1. 建立一个空白解决方案blank solution&#xff0c;如&#xff1a;d:/MyProject/MyProject.sln 2. 在d:/MyProject下建一个Web Application的根目录d:/MyProject/WebMis并设为http://localhost/WebMis的虚拟目录 3. 在WebMis目录下根据模块分别新建目录&#xff0c;如&#xf…

JQuery模板插件jquery.tmpl-动态ajax扩展

在上一篇JQuery模板插件-jquery.tmpl中介绍了这款插件。有时我们需要去动态的ajax去加载模板&#xff0c;或者数据&#xff0c;根据url参数或者其他信息加载不同的模板&#xff0c;数据。在我的某个项目中有这个需求&#xff0c;所以特地写成jquery工具函数&#xff0c;加入了本…

《JAVA-枚举》

2019独角兽企业重金招聘Python工程师标准>>> 枚举&#xff1a;枚举在C/C/c#/java中&#xff0c;是一个被命名的整型常数的集合&#xff0c;枚举在日常生活中很常见。 表示星期的SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,就是一个简单的例子 既然讲了枚…

在ASP.NET中使用WINDOWS模式登录SQL数据库

作者&#xff1a;未知 请作者速与本人联系经常发现有用户使用WINDOWS模式登录SQL SERVER&#xff0c;结果失败&#xff0c;提示&#xff1a; 用户 KEKC/ASPNET 登录失败。 说明: 执行当前 Web 请求期间&#xff0c;出现未处理的异常。请检查堆栈跟踪信息&#xff0c;以了解有…

时髦而精巧的Iphone墙纸收集

Iphone5如此的流行&#xff0c;我觉得我们有必要为我们的读者收集一套时尚的iphone墙纸。 知道设计和开发社区是多么喜欢装饰他们的移动设备&#xff0c;我们收集了各大社区最好的iphone墙纸&#xff0c;帮助你更好的装饰你的iphone设备。 因为有如此多的墙纸设计&#xff0c;我…

谷歌排名第一的编程语言,死磕它这两点,小白也能学的会!不信你看!

谷歌排名第一的编程语言时什么&#xff1f;毫无疑问&#xff1a;肯定是 Python。也难怪&#xff0c;作为大数据时代和人工智能时代的必备语言&#xff0c;Python 的优点太多了&#xff0c;语言简洁、易学、开发效率高、可移植性强......另外&#xff0c;更牛的地方是目前最热门…

UVA11059 Maximum Product

问题链接&#xff1a;UVA11059 Maximum Product。基础级练习题&#xff0c;用C语言编写程序。 题意简述&#xff1a;输入n个整数序列&#xff0c;有正有负&#xff0c;求这个序列中最大连续累乘的子序列&#xff0c;其最大的值为多少。如果结果为负数&#xff0c;则输出0。 问题…

.NET代码的保护

1没有绝对的保护 加密和破解都相对的 2用vs2002/2003/开发的代码 删除.cs/.vb文件只留 .dll和.aspx可以达到加密若要加密.aspx 可以把.aspx代码写入.csvs2005 beta1可以连.aspx都打包 3但是 dll还可以被反编译 所以高级的是加入混淆器不过这样也不是绝对的还是可以反编译混淆…

走向DBA[MSSQL篇] 面试官最喜欢的问题 ----索引+C#面试题客串

对大量数据进行查询时,可以应用到索引技术。索引是一种特殊类型的数据库对象&#xff0c;它保存着数据表中一列或者多列的排序结果&#xff0c;有效地使用索引可以提高数据的查询效率。大家面试初级、中级或者高级程序员的时候应该大部分都会被问到这样一些问题&#xff0c;你了…

“编程能力差的程序员,90%会输在这点上”谷歌AI专家:其实都是瞎努力

最近几年&#xff0c;我看过市面上很多 Python和人工智能的教程和书籍&#xff0c;它们大都这样讲&#xff1a;先从 Python 人工智能的历史讲起开始&#xff0c;再介绍的基本语法规则&#xff0c;Python 的 list, dict, tuple 等数据结构&#xff0c;最后学习机器学习、深度学习…

查询表空间使用情况

2019独角兽企业重金招聘Python工程师标准>>> SELECT a.tablespace_name "表空间名", total "表空间大小", free "表空间剩余大小", (total - free) "表空间使用大小", total / (1024 * 1024 * 1024) "表空间大小(…

一只端午节鸭蛋粽子的背后:AI 与农业

作者 | 硬核云顶宫责编 | Carol封图 | CSDN 下载自视觉中国今年的端午节&#xff0c;食品界的营销鬼才五芳斋又发了最新广告——《朋友们蘸起来》&#xff0c;这则视频通过一种科幻大片的风格展示了农业与科技的完美结合&#xff0c;可以说在一只端午节粽子背后有AI的养猪、种的…

一些实用的 Javascript 代码

οncοntextmenu"window.event.returnvaluefalse" 将彻底屏蔽鼠标右键<table border οncοntextmenureturn(false)><td>no</table> 可用于Table <body onselectstart"return false"> 取消选取、防止复制 οnpaste"return fa…

围观文件穿越操作

1. 打开文件用IoCreateFile&#xff0c;其他比较好发irp的&#xff08;比如删除操作&#xff09;走FSD irp 删除文件部分处理了删除正在运行的exe镜像部分&#xff0c;做法是方法是IAT Hook MmFlushImageSection 但是这样对于独占文件依旧不能处理&#xff0c;只好等到关机…

图论 - 欧拉回路

Description 欧拉回路是指不令笔离开纸面&#xff0c;可画过图中每条边仅一次&#xff0c;且可以回到起点的一条回路。现给定一个图&#xff0c;问是否存在欧拉回路&#xff1f;Input 测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数&#xff0c;分别是节点数N (…

学习 Linux,101: 引导系统

2019独角兽企业重金招聘Python工程师标准>>> 系列文章&#xff1a; http://www.ibm.com/developerworks/cn/views/linux/libraryview.jsp?search_by%E5%AD%A6%E4%B9%A0linux101 从 BIOS 到运行 Linux 系统 引导顺序 在我们深入了解启动加载程序&#xff08;比如 LI…

用Enter键取代tab键

1. this.TextBox1.Attributes.Add("OnKeyPress","<script>if keycode13 keycode9; return false;</script>");2. <input typetext οnkeydοwn"if (event.keyCode 13) event.keyCode 9;">

程序员:我受够了!不想再在小厂里干Java了!

你是否熟悉这样的情形&#xff1a;每天10点到公司&#xff0c;打开电脑&#xff1a;10个小时的增删改查&#xff0c;搬砖写代码的一天就这样开始了。刚毕业时候的你踌躇满志&#xff0c;按照自己的原定计划&#xff0c;这时候应该混到了阿里P6。可现在在小厂苦苦挣扎&#xff0…

iOS中UISearchBar(搜索框)使用总结

2019独角兽企业重金招聘Python工程师标准>>> iOS中UISearchBar(搜索框)使用总结 初始化&#xff1a;UISearchBar继承于UIView&#xff0c;我们可以像创建View那样创建searchBar UISearchBar * bar [[UISearchBar alloc]initWithFrame:CGRectMake(20, 100, 250, 40)…

Linux常用性能检测命令

一、uptime Uptime命令的显示结果包括服务器已经运行了多长时间&#xff0c;有多少登陆用户和对服务器性能的总体评估&#xff08;load average&#xff09;。load average值分别记录了上个1分钟&#xff0c;5分钟和15分钟间隔的负载情况&#xff0c;load average不是一个百…

怎样把DataGrid存放在ViewState中的无用数据卡掉

作者&#xff1a;无间道的博客http://www.cnblogs.com/wangsaokui/articles/10031.html 怎样把 DataGrid 存放在 ViewState 中的无用数据(有时候确实如此)卡掉&#xff0c;大家知道&#xff0c;一般而言DataGrid在ViewState中会存放表格中的所有数据&#xff0c;这样会导致View…

深度学习先驱 Yann LeCun 被骂到封推!AI 偏见真该甩锅数据集?

整理 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;最近&#xff0c;人工智能领域又发生了一次热热闹闹的争论&#xff0c;随后演变成一场偏离轨道的争吵&#xff0c;目前以 Yann 道歉封推暂告一段落......争论来龙去脉这次争论的主角是图灵奖得主、人工智能标杆性人物…

JS加强学习-DOM学习01

JavaScript由三个部分组成&#xff1a;ECMAScript、DOM、BOM。前面已经学习了ECMAScript中的基础内容&#xff0c;现在可以开始学习DOM部分了&#xff0c;在DOM中更多的是实际效果的展现。 1. DOM定义 DOM&#xff1a;document object model 文档对象模型 它是将整个页面文档封…

android 游戏引擎libgdx demo cuboc分析

开始学习android游戏开发也有一段时间了,挑选libgdx这个游戏引擎来进行学习和开发。Libgdx是一款支持2D与3D游戏开发的游戏类库,并且它是夸平台的。例如你可以在windos下开发&#xff0c;同样的代码也可以运行在android上。 刚开始学习这个游戏引擎可能会感觉无从下手&#…

倒计时1天 | 张钹院士领衔,AI开发者大会20大论坛全攻略!

2020年7月3—4日&#xff0c;由 CSDN 主办的第三届 AI 开发者大会&#xff08;AI ProCon 2020&#xff09;&#xff08;大会官网&#xff1a;https://aiprocon.csdn.net/&#xff09;将以线上直播的形式与大家相见。本次大会历时2天&#xff0c;一次性设立6大主题、20大精彩分论…

在页面中导入文件

1. <% Response.WriteFile ("Yourfile.inc") %> 2. Server.Execute("Yourfile.inc")