using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.Operation;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.ConvertElement;
using Kingdee.BOS.Core.Metadata.ConvertElement.ServiceArgs;
using Kingdee.BOS.Core.Interaction;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using System.Data;
namespace K3.ZY.SAL
{
[Description("根据客户资质下推")]
public class CheckPush : AbstractOperationServicePlugIn
{
///
/// 审核操作完成,单据状态已经更改,但是还没有提交事务时,触发此事件:
///
///
public override void OnPreparePropertys(PreparePropertysEventArgs e)
{
//e.FieldKeys.Add("");将需要应用的字段Key加入
e.FieldKeys.Add("CustomerID_Id");
}
///
/// 因为此事件触发时,还在事务保护中,因此适合进行数据同步;
/// 审核后自动下推,如果下推失败,需要放弃审核,因此,放在此事件中处理(事务中)
///
public override void EndOperationTransaction(EndOperationTransactionArgs e)
{
try
{
DataSet ds = Kingdee.BOS.ServiceHelper.DBServiceHelper.ExecuteDataSet(this.Context,
"select FClientCode,FUalifiedDate,FNUMBER,b.FNAME from T_BD_CUSTOMER a left join T_BD_CUSTOMER_L b on b.FCUSTID=a.FCUSTID where a.FCUSTID='" + e.DataEntitys[0]["CustomerID_Id"] + "'");
string customer = ds.Tables[0].Rows[0]["FNAME"].ToString();
//许可号为空或者到期
if (ds.Tables[0].Rows[0]["FClientCode"] == null || (DateTime.Compare(DateTime.Now, Convert.ToDateTime(ds.Tables[0].Rows[0]["FUalifiedDate"]))) > 0)
{
this.ShowK3DisplayMessage(customer);
this.DoPush(this.BusinessInfo.GetForm().Id, "STK_TransferDirect",
(from p in e.DataEntitys select Convert.ToInt64(p[0])).ToList());
}
else
{
this.DoPush(this.BusinessInfo.GetForm().Id, "SAL_OUTSTOCK",
(from p in e.DataEntitys select Convert.ToInt64(p[0])).ToList());
}
}
catch (Exception ex)
{
throw ex;
}
}
///
/// 自动下推并保存
///
/// 源单FormId
/// 目标单FormId
/// 源单内码
private void DoPush(string sourceFormId, string targetFormId, List
{
// 获取源单与目标单的转换规则
IConvertService convertService = ServiceHelper.GetService
var rules = convertService.GetConvertRules(this.Context, sourceFormId, targetFormId);
if (rules == null || rules.Count == 0)
{
throw new KDBusinessException("", string.Format("未找到{0}到{1}之间,启用的转换规则,无法自动下推!", sourceFormId, targetFormId));
}
// 取勾选了默认选项的规则
var rule = rules.FirstOrDefault(t => t.IsDefault);
// 如果无默认规则,则取第一个
if (rule == null)
{
rule = rules[0];
}
// 开始构建下推参数:
// 待下推的源单数据行
List
foreach (var billId in sourceBillIds)
{// 把待下推的源单内码,逐个创建ListSelectedRow对象,添加到集合中
srcSelectedRows.Add(new ListSelectedRow(billId.ToString(), string.Empty, 0, sourceFormId));
// 特别说明:上述代码,是整单下推;
// 如果需要指定待下推的单据体行,请参照下句代码,在ListSelectedRow中,指定EntryEntityKey以及EntryId
//srcSelectedRows.Add(new ListSelectedRow(billId.ToString(), entityId, 0, sourceFormId) { EntryEntityKey = "FEntity" });
}
// 指定目标单单据类型:情况比较复杂,没有合适的案例做参照,示例代码暂略,直接留空,会下推到默认的单据类型
string targetBillTypeId = string.Empty;
// 指定目标单据主业务组织:情况更加复杂,需要涉及到业务委托关系,缺少合适案例,示例代码暂略
// 建议在转换规则中,配置好主业务组织字段的映射关系:运行时,由系统根据映射关系,自动从上游单据取主业务组织,避免由插件指定
long targetOrgId = 0;
// 自定义参数字典:把一些自定义参数,传递到转换插件中;转换插件再根据这些参数,进行特定处理
Dictionary
// 组装下推参数对象
PushArgs pushArgs = new PushArgs(rule, srcSelectedRows.ToArray())
{
TargetBillTypeId = targetBillTypeId,
TargetOrgId = targetOrgId,
CustomParams = custParams
};
// 调用下推服务,生成下游单据数据包
ConvertOperationResult operationResult = convertService.Push(this.Context, pushArgs, OperateOption.Create());
// 开始处理下推结果:
// 获取下推生成的下游单据数据包
DynamicObject[] targetBillObjs = (from p in operationResult.TargetDataEntities select p.DataEntity).ToArray();
if (targetBillObjs.Length == 0)
{
// 未下推成功目标单,抛出错误,中断审核
throw new KDBusinessException("", string.Format("由{0}自动下推{1},没有成功生成数据包,自动下推失败!", sourceFormId, targetFormId));
}
// 对下游单据数据包,进行适当的修订,以避免关键字段为空,自动保存失败
// 示例代码略
// 读取目标单据元数据
IMetaDataService metaService = ServiceHelper.GetService
var targetBillMeta = metaService.Load(this.Context, targetFormId) as FormMetadata;
// 构建保存操作参数:设置操作选项值,忽略交互提示
OperateOption saveOption = OperateOption.Create();
// 忽略全部需要交互性质的提示,直接保存;
saveOption.SetIgnoreWarning(true); // 忽略交互提示
saveOption.SetInteractionFlag(this.Option.GetInteractionFlag()); // 如果有交互,传入用户选择的交互结果
// using Kingdee.BOS.Core.Interaction;
saveOption.SetIgnoreInteractionFlag(this.Option.GetIgnoreInteractionFlag());
//// 如下代码,强制要求忽略交互提示(演示案例不需要,注释掉)
//saveOption.SetIgnoreWarning(true);
//// using Kingdee.BOS.Core.Interaction;
//saveOption.SetIgnoreInteractionFlag(true);
// 调用保存服务,自动保存
ISaveService saveService = ServiceHelper.GetService
var saveResult = saveService.Save(this.Context, targetBillMeta.BusinessInfo, targetBillObjs, saveOption, "Save");
// 判断自动保存结果:只有操作成功,才会继续
if (this.CheckOpResult(saveResult, saveOption))
{
return;
}
}
///
/// 判断操作结果是否成功,如果不成功,则直接抛错中断进程
///
/// 操作结果
/// 操作参数
///
private bool CheckOpResult(IOperationResult opResult, OperateOption opOption)
{
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;
// 抛出交互错误,把交互信息传递给前端
new KDInteractionException(opOption, opResult.Sponsor);
}
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;
}
private void ShowK3DisplayMessage(string customer)
{
// 判断操作校验是否通过 : 如果通过了校验,则不用给出提示
if (this.OperationCheck1())
{
return;
}
// 定义交互消息标识,以与其他交互消息区分开
string spensorKey = "JDSample.ServicePlugIn.Operation.S160425ShowInteractionOpPlug.ShowK3DisplayMessage";
// 判断用户是否已经确认过本交互信息
if (this.Option.HasInteractionFlag(spensorKey))
{
// this.Option.HasInteractionFlag()在如下两种情况下,返回true:
// 1. 用户已经确认过本交互信息,并选择了继续
// 2. 外围代码,在调用本操作前,通过如下代码,强制要求不显示交互消息:
// this.Option.SetIgnoreInteractionFlag(true);
// 因此,如果 this.Option.HasInteractionFlag() == true, 表示需要忽略本交互
return;
}
// 提示信息的列标题,以“~|~”分开两列
string titleMsg = "顾客无资质";
// 对应的提示信息格式,以"~|~"分开两列,以{n}进行占位
string errMsg = customer+ "无资质或已到期,是否下推至直接调拨单";
// 构建消息模型K3DisplayerModel,在此对象中,添加消息内容
K3DisplayerModel model = K3DisplayerModel.Create(Context, titleMsg);
// 消息内容:可以添加多行
// 消息抬头
model.Option.SetVariableValue(K3DisplayerModel.CST_FormTitle, "客户资质提醒");
// 是否继续按钮
model.OKButton.Visible = true;
model.OKButton.Caption = new LocaleValue("是", Context.UserLocale.LCID);
model.CancelButton.Visible = true;
model.CancelButton.Caption = new LocaleValue("否", Context.UserLocale.LCID);
// 创建一个交互提示错误对象KDInteractionException:
// 通过throw new KDInteractionException()的方式,向操作调用者,输出交互信息
KDInteractionException ie = new KDInteractionException(this.Option, spensorKey);
// 提示信息显示界面
ie.InteractionContext.InteractionFormId = FormIdConst.BOS_K3Displayer;
// 提示内容
ie.InteractionContext.K3DisplayerModel = model;
// 是否需要交互
ie.InteractionContext.IsInteractive = true;
// 抛出错误,终止流程
throw ie;
}
///
/// 操作校验:如果校验不通过,则需要给出交互提示。
///
/// 用户在交互界面上录入的内容
///
///
/// 本案例,强制返回校验不通过,以演示交互信息显示效果
///
private bool OperationCheck1()
{
return false;
}
}
}
捕获.PNG(214.04KB)
推荐阅读