背景

经常有某个汇总子表的数量到主表的总数量,或者汇总子表的总价到主表的总价这种需求。

传统的做法:

1、就是为每个子表实体单独写成一个插件,但是这样不好复用。

2、主表的汇总字段是汇总货币类型,但是不能实时计算,得手动在页面上重新计算,如下图,点刷新才会触发计算

这里有幸阅读了网上一位前辈【疯吻IT】4年前写的文章,继承了他的思路实现了增删改重新触发汇总子表的某个字段到主表某个字段上。

效果图:

话不多说,上代码。

#region << 版 本 注 释 >>
/*----------------------------------------------------------------
* 项目名称 :Vyung.CRM.Plugins.Plugin
* 项目描述 :
* 类 名 称 :SumSub2Head
* 类 描 述 :将子表的字段合计到头表的某个字段
* 增删改实时触发头表汇总字段更新
* 所在的域 :cangfeng-PC
* 命名空间 :Vyung.CRM.Plugins.Plugin
* 机器名称 :CANGFENG-PC
* CLR 版本 :4.0.30319.42000
* 作 者 :cangfeng
* 创建时间 :2018/11/28 13:23:28
* 更新时间 :2018/11/28 13:23:28
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ cangfeng 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Vyung.CRM.Plugins.Common; namespace Vyung.CRM.Plugins.Plugin
{ public class SumSub2Head : IPlugin
{
//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount
public static string unsecure = "";
public SumSub2Head(string unsecureConfig, string secureConfig)
{
if (String.IsNullOrWhiteSpace(unsecureConfig) ||
String.IsNullOrWhiteSpace(unsecureConfig))
{
throw new InvalidPluginExecutionException("Unsecure and secure strings are required for this plugin to execute.");
} unsecure = unsecureConfig;
}
public void Execute(IServiceProvider serviceProvider)
{
#region 上下文实体信息初始化
ITracingService tracingservice = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
IOrganizationService serviceAdmin = serviceFactory.CreateOrganizationService(null);
bool isCreate = context.MessageName == "Create";
bool isUpdate = context.MessageName == "Update";
bool isDelete = context.MessageName == "Delete";
Entity target = null;
EntityReference targetref = null; //当前的实体
Entity m_CurrentEntity = null; if (context.InputParameters.Contains("Target"))
{
if (context.InputParameters["Target"] is Entity)
target = (Entity)context.InputParameters["Target"];
else if (context.InputParameters["Target"] is EntityReference)
targetref = (EntityReference)context.InputParameters["Target"];
}
Guid entityId;
string logicalName;
if (target == null)
{
entityId = targetref.Id;
logicalName = targetref.LogicalName;
}
else
{
entityId = target.Id;
logicalName = target.LogicalName;
}
#endregion #region 基本实体信息初始化
Entity preEntity = null;
Entity postEntity = null; if (context.PreEntityImages.Contains("PreImage") && context.PreEntityImages["PreImage"] != null)
{
preEntity = context.PreEntityImages["PreImage"];
}
if (context.PostEntityImages.Contains("PostImage") && context.PostEntityImages["PostImage"] != null)
{
postEntity = context.PostEntityImages["PostImage"];
}
int intStage = context.Stage;
#endregion try
{
//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount
var param = unsecure.Split(','); #region 前期事件
if (intStage == 10 || intStage == 20)
{
#region 创建事件
if (isCreate)
{ }
#endregion #region 更新事件
if (isUpdate)
{ }
#endregion #region 删除事件
if (isDelete)
{ }
#endregion }
#endregion #region 后期事件给m_CurrentEntity赋值
else
{
#region 创建事件
if (isCreate)
{
m_CurrentEntity = target;
}
#endregion #region 更新事件
if (isUpdate)
{ //m_CurrentEntity = (Entity)context.InputParameters["Target"];
m_CurrentEntity = target;
m_CurrentEntity[param[1]] = preEntity[param[1]]; }
#endregion #region 删除事件
if (isDelete)
{
//我擦,删除居然不是entity类型,坑人targetref
//EntityReference er = context.InputParameters["Target"] as EntityReference;
//m_CurrentEntity = new Entity(er.LogicalName);
//m_CurrentEntity.Id = er.Id;
//m_CurrentEntity[param[1]] = preEntity[param[1]]; m_CurrentEntity = new Entity(targetref.LogicalName);
m_CurrentEntity.Id = targetref.Id;
m_CurrentEntity[param[1]] = preEntity[param[1]];
}
#endregion
}
#endregion //获取当前记录的主表id,根据主表id使用Linq获取对应的其他明细记录的需要统计的字段。如:amount
OrganizationServiceContext svcContext = new OrganizationServiceContext(serviceAdmin);
var ents = svcContext.CreateQuery(m_CurrentEntity.LogicalName).Where(e => e[param[1]] == m_CurrentEntity[param[1]] && e[param[0]] != null).Select(e => e[param[0]]);
decimal amount = 0;
foreach (var ent in ents)
{
amount += Convert.ToDecimal(((Money)ent).Value);
} //根据当前记录的主表id,查出首条头记录
var primaryEnt = svcContext.CreateQuery(param[2]).Where(e => e[param[1]] == m_CurrentEntity[param[1]]).FirstOrDefault(); //给头的汇总字段赋值
if (primaryEnt != null)
{
primaryEnt[param[3]] = new Money(amount); //linq更新实体
svcContext.UpdateObject(primaryEnt);
svcContext.SaveChanges();
}
}
catch (Exception e)
{
throw new InvalidPluginExecutionException("错误:" + e.Message + "[" + this.GetType().ToString() + "]");
}
}
}
}

使用步骤:

1、准备好unsecureConfig字段,如下

//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount

2、注册插件

3、注册步骤

create:

update:

update 的前镜像

delete:

delete的前镜像

Ok,插件写好之后,以后就只需要注册,并且在unsecureConfig配置好对应的汇总字段和表就OK了。

如果本文有帮助到你,就给个推荐吧O(∩_∩)O~

Microsoft Dynamics CRM 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)的更多相关文章

  1. Microsoft Dynamics CRM 2011 当您在 大型数据集上执行 RetrieveMultiple 查询很慢的解决方法

    症状 当您在 Microsoft Dynamics CRM 2011 年大型数据集上执行 RetrieveMultiple 查询时,您会比较慢. 原因 发生此问题是因为大型数据集缓存 Retrieve ...

  2. Microsoft Dynamics CRM 2013 --选项集的多选

    由于从Microsoft Dynamics CRM 2011到Microsoft Dynamics CRM 2013,界面的风格发生了很大的变化 故原先在2011上开发的选项集多选在2013上面已经不 ...

  3. Microsoft Dynamics CRM 常用JS语法(已转成vs2017语法提示)

    背景 最近接触到Microsoft Dynamics CRM的开发.前端js是必不可少的部分,奈何没有一个语法提示,点不出来后续的语句. 在vscode上面搜索插件的时候发现,有一个大神写的插件htt ...

  4. Microsoft Dynamics CRM 分销行业解决方案

    Microsoft Dynamics CRM 分销行业解决方案 方案亮点 360度动态渠道信息管理 充分的客户细分 全面的业务代表考核指标 业务代表管理和能力建设 业务代表过程管理 业务代表费用管理 ...

  5. K2 BPM+Microsoft Dynamics CRM,妥妥的~

    啊~~~~七夕 ▼ 你比巴西少一xi 你比山西多四xi 对有情人来说今天就是情人节,对单身汪来说,今天就是个星期四. but,软件也是要秀恩爱的! ♥ 晒晒我家亲爱的CRM,它的全名叫Microsof ...

  6. 利用K2和Microsoft Dynamics CRM构建业务App的5大理由

    Microsoft Dynamics CRM提供了一个绝佳的客户关系管理平台,使您能够创建各种以客户为中心的解决方案.然而,通过将K2的企业业务流程功能与Microsoft Dynamics CRM相 ...

  7. 一、Microsoft Dynamics CRM 4.0 SDK概述

    Chapter 1. Microsoft Dynamics CRM 4.0 SDK Overview(SDK概述) You are probably reading this book because ...

  8. Dynamic CRM 2015学习笔记(6)没有足够的权限 - 您没有访问这些记录的权限。请联系 Microsoft Dynamics CRM 管理员

    我们经常遇到下面这种问题:没有足够的权限 - 您没有访问这些记录的权限.请联系 Microsoft Dynamics CRM 管理员.  下面将详细介绍下如何解决这种问题:进不了CRM系统:进了CRM ...

  9. Microsoft Dynamics CRM4.0 JScript 过滤lookup 出现 Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止。

    一.现象:JScript过滤lookup字段,选择lookup字段出现下图的情况: 出现:Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止.请将这台Micro ...

随机推荐

  1. Docker 安装 - Docker 与前端(一)

    Docker 是一个开源的容器引擎,可以方便的对容器进行管理.作为一种新兴的虚拟化方式,跟传统的虚拟化方式相比具有众多优势.<Docker 遇见前端>系列文章,旨在记录如何通过 docke ...

  2. Python datetime.md

    datetime datetime模块包含了一些用于时间解析.格式化.计算的函数. Times 时间值由time类来表示, Times有小时, 分, 秒和微秒属性. 以及包含时区信息. 初始化time ...

  3. UI之富文本编辑器-UEditor

    在做Web应用时,经常会进行富文本编辑,常用的富文本编辑器有很多,比如CuteEditor.CKEditor.NicEditor.KindEditor.UEditor等等. 在这里为大家推荐百度推出的 ...

  4. day3-课堂笔记

    函数有2种: 1种是有返回值的,不改变对象本身 1种是没有返回值的,改变对象本身   eval函数就是实现list.dict.tuple与str之间的转化(只能把类似格式的字符串进行相应转换)str函 ...

  5. JAVA框架 Spring 约束配置本地资源

    一:粘贴约束url:http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.or ...

  6. dom4j加载xml文件

    ## dom4j加载xml文件 ``` // 1. 加载xml文件 InputStream is = MyTest.class.getResourceAsStream("user.xml&q ...

  7. day08(补)

    今日学习内容 1.文件重写方法 2.函数基本知识 文件处理: 打开文件 读/写文件 关闭文件 文件指针移动,只有t模式下的read(n),n代表的字符个数其余都是以字节为单位 f.seek有两个参数( ...

  8. 一键安装Docker图形化管理界面-Shipyard

    Shipyard是一款开源的图形化的Docker管理工具,记得以前安装很麻烦的,现在官方有了自动安装脚本,使用非常方便.复制.粘贴.使用,就这么简单.先不研究他是如何实现的,安装使用起来再说. $ c ...

  9. Luence

    Luence 是Apache软件基金会的一个项目,是一个开发源码的全文检索引擎工具包,是一个全文检索引擎的一个架构.提供了完成的查询引擎和检索引擎,部分文本分析引擎. 全文检索程序库,虽然与搜索引擎相 ...

  10. 【LeetCode92】Reverse Linked List II★★

    题目描述: 解题思路: 题目大意:给定一个链表,反转第m到第n个结点部分,m.n满足1 ≤ m ≤ n ≤ length of list. 解题思路参照LeetCode206题,用迭代法,不过要注意以 ...