Microsoft Dynamics CRM 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)
背景
经常有某个汇总子表的数量到主表的总数量,或者汇总子表的总价到主表的总价这种需求。
传统的做法:
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 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)的更多相关文章
- Microsoft Dynamics CRM 2011 当您在 大型数据集上执行 RetrieveMultiple 查询很慢的解决方法
症状 当您在 Microsoft Dynamics CRM 2011 年大型数据集上执行 RetrieveMultiple 查询时,您会比较慢. 原因 发生此问题是因为大型数据集缓存 Retrieve ...
- Microsoft Dynamics CRM 2013 --选项集的多选
由于从Microsoft Dynamics CRM 2011到Microsoft Dynamics CRM 2013,界面的风格发生了很大的变化 故原先在2011上开发的选项集多选在2013上面已经不 ...
- Microsoft Dynamics CRM 常用JS语法(已转成vs2017语法提示)
背景 最近接触到Microsoft Dynamics CRM的开发.前端js是必不可少的部分,奈何没有一个语法提示,点不出来后续的语句. 在vscode上面搜索插件的时候发现,有一个大神写的插件htt ...
- Microsoft Dynamics CRM 分销行业解决方案
Microsoft Dynamics CRM 分销行业解决方案 方案亮点 360度动态渠道信息管理 充分的客户细分 全面的业务代表考核指标 业务代表管理和能力建设 业务代表过程管理 业务代表费用管理 ...
- K2 BPM+Microsoft Dynamics CRM,妥妥的~
啊~~~~七夕 ▼ 你比巴西少一xi 你比山西多四xi 对有情人来说今天就是情人节,对单身汪来说,今天就是个星期四. but,软件也是要秀恩爱的! ♥ 晒晒我家亲爱的CRM,它的全名叫Microsof ...
- 利用K2和Microsoft Dynamics CRM构建业务App的5大理由
Microsoft Dynamics CRM提供了一个绝佳的客户关系管理平台,使您能够创建各种以客户为中心的解决方案.然而,通过将K2的企业业务流程功能与Microsoft Dynamics CRM相 ...
- 一、Microsoft Dynamics CRM 4.0 SDK概述
Chapter 1. Microsoft Dynamics CRM 4.0 SDK Overview(SDK概述) You are probably reading this book because ...
- Dynamic CRM 2015学习笔记(6)没有足够的权限 - 您没有访问这些记录的权限。请联系 Microsoft Dynamics CRM 管理员
我们经常遇到下面这种问题:没有足够的权限 - 您没有访问这些记录的权限.请联系 Microsoft Dynamics CRM 管理员. 下面将详细介绍下如何解决这种问题:进不了CRM系统:进了CRM ...
- Microsoft Dynamics CRM4.0 JScript 过滤lookup 出现 Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止。
一.现象:JScript过滤lookup字段,选择lookup字段出现下图的情况: 出现:Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止.请将这台Micro ...
随机推荐
- 三种方法实现java调用Restful接口
1,基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring ...
- vscode对Vue文件的html部分格式化失效问题解决办法
使用vscode编辑vue文件时发现突然格式化代码不会对<template> </template>之间的html生效了,解决办法很简单 文件 --> 首选项 ---&g ...
- 一、HttpServletRequest接口 二、HttpServletReponse接口 三、POST和GET请求方式及其乱码处理 四、ServletContext对象和ServletConfig对象
一.HttpServletRequest接口 内部封装了客户端请求的数据信息 接收客户端的请求参数.HTTP请求数据包中配置参数 ###<1>常用方法 getContextPath()重要 ...
- 使用C#删除一个字符串数组中的空字符串
C#中要如何才能删除一个字符串数组中的空字符串呢?随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化.以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和过滤.C#3. ...
- 第二次项目冲刺(Beta版本)2017/12/6
一.任务明细 二.燃尽图 三.站立式会议 1.照片(随后上传) 2.会议任务安排 四.总结 第一天冲刺,准备工作不足啊,期末了,最近大家都比较忙吧,开始战斗吧.
- PyQt5 的几个核心模块作用
QtCore 包含了核心的非GUI功能.此模块用于处理时间.文件和目录.各种数据类型.流.URL.MIME类型.线程或进程. QtGui 包含类窗口系统集成.事件处理.二维图形.基本成像.字体和文 ...
- 【洛谷】【单调队列】P2032 扫描
[题目描述:] 有一个 1 ∗ n 的矩阵,有 n 个正整数. 现在给你一个可以盖住连续的 k 的数的木板. 一开始木板盖住了矩阵的第 1 ∼ k 个数,每次将木板向右移动一个单位,直到右端与第 n ...
- 随手练——小米OJ 高弗雷勋爵
高弗雷勋爵 题目链接:https://code.mi.com/problem/list/view?id=113 这个解法比较暴力,主要需要注意的是一颗子弹 弹死两个及以上的情况. #include & ...
- Kubernetes1.91(K8s)安装部署过程(二)--证书kubeconfig文件创建
前提: 安装kubelet工具,参考:https://jimmysong.io/kubernetes-handbook/practice/kubectl-installation.html 如遇*** ...
- 高斯-克吕格投影与UTM投影
高斯-克吕格投影与UTM投影 高斯-克吕格(Gauss-Kruger)投影与UTM投影(Universal Transverse Mercator,通用横轴墨卡托投影)都是横轴墨卡托投影的变种,目前一 ...