实现思路:
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);}
引用: