D365API文档

系统设置

1.如何在表单的子网格右上角隐藏关联视图按钮

表单编辑器

2.如何控制子网格按钮的显示隐藏

Dynamics 365子网格根据条件隐藏新建/添加按钮 - 微软MVP(15-18)罗勇 - 博客园

前台

1.访问后台方法

   访问后台的方法有很多,有通过action访问的,有通过workflow访问的,js的直接查询方法也有两种,一种通过直接查询实体名,只能通过主键查询。另一种fetch可以更灵活的查询。

//直接查询实体
var rest = new fwREST();
            var objStr = "accounts?$select=hms_sapcustomerid&$filter=accountid eq (" + customerid + ")";
            rest.get(objStr).then(function (ob) {
                if (ob.value.error != undefined || ob.value.length > 1) {

                } else {
                   var hms_sapcustomerid = ob.value[0]["hms_sapcustomerid"];
                }
});
//请求的封装方法
this.executeWebAPI = function (requestType, requestUri, requestData, successCallback, errorCallback, isAsync) {
        var req = new XMLHttpRequest();

        if (isAsync == null) {
            isAsync = true;
        }
        req.open(requestType, encodeURI(requestUri), isAsync);
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Prefer", "odata.include-annotations=*");
        req.onreadystatechange = function () {
            if (this.readyState == 4 /* complete */) {
                req.onreadystatechange = null;
                if (this.status == 200) {
                    if (successCallback) {
                        successCallback(JSON.parse(this.responseText));
                    }
                }
                else if (this.status == 204) {
                    if (successCallback) {
                        successCallback(this.getResponseHeader("OData-EntityId"));
                    }
                }
                else {
                    var error = JSON.parse(this.response).error;
                    if (errorCallback) { errorCallback(error); }
                    else { Xrm.Utility.alertDialog(error.message); }
                }
            }
        };
        req.send(JSON.stringify(requestData));
    }
//fetch的查询方式
var cancelorderId = formContext.data.entity.getId().replace("{", "").replace("}", "");
                if (!!cancelorderId) {
                    var fetchxml = "<fetch mapping='logical' aggregate='false'>" +
                        "<entity name='hms_changeconfirmeddetail'>" +
                        "<attribute name='hms_changeconfirmeddetailid' />" +//主键
                        "<filter  type='and' >" +
                        "<condition attribute='hms_cancelapplyid' operator='eq'  value='" + cancelorderId + "' />" +
                        "<condition attribute='hms_changetype' operator='not-null' />" +
                        "</filter>" +
                        "</entity>" +
                        "</fetch>";
                    var req = new XMLHttpRequest();
                    req.open("get", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/hms_changeconfirmeddetails?fetchXml=" + encodeURI(fetchxml), false);
                    req.setRequestHeader("Accept", "application/json");
                    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                    req.setRequestHeader("OData-MaxVersion", "4.0");
                    req.setRequestHeader("OData-Version", "4.0");
                    req.onreadystatechange = function () {
                        if (this.readyState == 4) {
                            if (this.status == 200) {
                                var data = JSON.parse(this.responseText);
                                if (data.value.length > 0) {
                                    show = true;
                                } else {
                                    show = false;
                                }
                            }
                        }
                    };
                    req.send();
                }
//查询结果用于过滤lookup字段的可选范围
  var clientURL = formContext.context.getClientUrl();
            var uri = clientURL + "/api/data/v8.0/accounts?$filter=accountid eq " + customerid + "&$select=hms_sapcustomerid";
            HMS.CRMUtil.executeWebAPI("GET", uri, null, function (data) {
                var length = data.value.length;
                if (length > 0) {
                    var hms_sapcustomerid = data.value[0].hms_sapcustomerid; 
                    var contactWithCustomer = "<filter type='and'>" +
                        "<condition attribute='hms_name' operator='eq' value='" + hms_sapcustomerid + "'/>" +
                        "</filter>"
                    formContext.getControl("hms_soldtoparty").addCustomFilter(contactWithCustomer, "hms_sapsoldtoparty");
                }
            }, null, false);

2.给lookup字段赋值

formContext.getAttribute("hms_salesorganizationid").setValue([{ id: hms_salesorganizationid, name: ob.value[0]["hms_name"], entityType: 'hms_salesorganization' }]);

3.判断是否页面已保存

if (Xrm.Page.data.entity.getIsDirty()) {
        Xrm.Utility.alertDialog("页面尚未保存!");
        return;
    }

4.阻止保存语句

context.getEventArgs().preventDefault();

5.提示

// 弹窗提示
var alertStrings = { confirmButtonLabel: "Yes", text: "This is an alert.", title: "Sample title" };
var alertOptions = { height: 120, width: 260 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(
    function (success) {
        console.log("Alert dialog closed");
    },
    function (error) {
        console.log(error.message);
    }
);
//上方提示栏位
formContext.ui.setFormNotification("未查询到产品型号相关信息!!", "WARNING", "salesPriceCheckError");
setTimeout(function () {
    formContext.ui.clearFormNotification('salesPriceCheckError');
}, 5000);

6.设置字段是否必填

 formContext.getAttribute("hms_soldtoparty").setRequiredLevel("none");//设置该字段为非必填

 formContext.getAttribute("hms_soldtoparty").setRequiredLevel("required");//设置该字段为必填

7.限制lookup字段的查询范围

 formContext.getControl("hms_soldtoparty").addCustomFilter(allContacts, "hms_sapsoldtoparty");

8.设置字段可编辑

formContext.getControl("hms_changetype").setDisabled(false); //可编辑
formContext.getControl("hms_changetype").setDisabled(true); //不可编辑

9.设置可见性

//设置字段可见性
formContext.getControl(arg).setVisible(true);//可见
formContext.getControl(arg).setVisible(false);//不可见
//设置选项卡可见性
Xrm.Page.ui.tabs.get("mainform").setVisible(true);
//设置选项卡内某个节可见性
Xrm.Page.ui.tabs.get("mainform").sections.get("doactioniframe").setVisible(true);

10.打开指定实体指定ID的表单

var newid = dataobj.Data.id;
var entityFormOptions = {};
entityFormOptions["entityName"] = "salesorder";
entityFormOptions["entityId"] = newid;

Xrm.Navigation.openForm(entityFormOptions).then(
function (success) {
    console.log(success);
},
function (error) {
    console.log(error);
});

11.多项选项集字段

11.1 设置可选值

//通用过滤选项集值的函数 attributeName:需要过滤的选项集的属性名 valuesArr:需要保留的选项值
   function filterOptionSet (attributeName, valuesArr) {
        var optionSet = Xrm.Page.ui.controls.get(attributeName);
        var optionSetValues = optionSet.getAttribute().getOptions();
        optionSet.clearOptions();
        optionSetValues.forEach(function (element) {
            var index = valuesArr.indexOf(element.value);
            if (index === -1) {
                optionSet.removeOption(element.value);
            }
            else {
                optionSet.addOption(element);
            }
        }, valuesArr);
    }

11.2 自定义选择框选项

new Xrm.OptionSetItem(1,'111');
let optionsetControl = Xrm.Page.getControl(field);
optionsetControl.clearOptions();
 optionsetControl.addOption(item);

11.3 隐藏不需要的选项

//先判断字段是否可编辑,考虑历史数据的显示
filterOptionSet("hms_documenttype", [10, 20, 30, 40]);

function filterOptionSet(attributeName, valuesArr) {
    var fieldstatus = formContext.getControl(attributeName).getDisabled();
    if (!fieldstatus) {
        var optionSet = Xrm.Page.ui.controls.get(attributeName);
        var optionSetValues = optionSet.getAttribute().getOptions();
        optionSetValues.forEach(function (element) {
            var index = valuesArr.indexOf(element.value);
            if (index > -1) {
                optionSet.removeOption(element.value);
            }
        }, valuesArr);
        var fieldvalue = Xrm.Page.getAttribute(attributeName).getValue();
        if (valuesArr.indexOf(fieldvalue) > -1) {
            Xrm.Page.getAttribute(attributeName).setValue(null);
        }
    }
}

11.4 设置值

//给多项选项集字段取值时,取到的是字符串“1,2,3”,需要转成数组,然后注意转成数字数组后赋值给字段才可。
var new_majorcusttype = ob.value[0]["new_majorcusttype"];
if (new_majorcusttype != null) {
    debugger;
    var arr = new_majorcusttype.split(",");
    let numArray = arr.map(str => parseInt(str));
    formContext.getAttribute("hms_majorcusttype").setValue(numArray);
}

12.给lookup字段设置默认查找视图

    formContext.getControl("hms_systemuserid").setDefaultView("EBD6ED09-6686-EB11-B02E-00155D93E403");

13.获取当前操作人员ID

var systemuserid = Xrm.Page.context.getUserId().replace("{", "").replace("}", "");

14.获取当前表单实体ID

 var id = Xrm.Page.data.entity.getId().replace("{", "").replace("}", "");

15.设置窗体lookup类型字段的查询视图

16.点击按钮弹出人员选择或者其他选择弹窗

var viewId = "{00000000-0000-0000-0000-000000000001}"//HMS.CRMUtil.newGUID();

        //2. 获取自定义查询实体的type code,避免同一个实体在不同系统中typecode不相同带来的问题
        var objectTypeCode = Mscrm.EntityPropUtil.EntityTypeName2CodeMap["hms_faeengineercard"];
        //4. 构造自定义视图
        var layoutXML = "<grid name='resultset' object='" + objectTypeCode + "' jump='hms_name' select='1' icon='0' preview='0'>" +
            "<row name='result' id='hms_faeengineercard'>" +
            "<cell name='hms_systemuserid' width='150' />" +
            "<cell name='hms_engineerstatus' width='80' />" +
            "<cell name='hms_belongtoarea' width='80' />" +
            "<cell name='hms_onhandticketnum' width='90' />" +
            "<cell name='hms_skilledservicetype' width='200' />" +
            "<cell name='hms_skilledproduct' width='200' />" +
            "<cell name='hms_skilledarea' width='200' />" +
            "<cell name='hms_domainname' width='150' />" +
            "</row>" +
            "</grid>";

        var customerView = {
            Type: 0, //固定值0
            fetchXml: fetchXml,
            id: viewId,
            layoutXml: layoutXML,
            name: viewName,
            recordType: objectTypeCode
        };

        //5. 构造dialogOption
        var lookupOptions = {
            defaultEntityType: "hms_faeengineercard",
            entityTypes: ["hms_faeengineercard"],
            viewIds: [viewId],
            allowMultiSelect: false,
            defaultViewId: viewId,
            customViews: [customerView]
        };

        //6. 构造dialog调用参数
        Xrm.Utility.lookupObjects(lookupOptions)
            .then(function (result) {
                debugger;
                var domainName = JSON.parse(result[0].keyValues).hms_domainname.value;
                var systemUserId = HMS.SupportTicket.RibbonEvent.getSystemUserIdByDomainName("'" + domainName + "'");

                var clientURL = Xrm.Page.context.getClientUrl();
                var uri = clientURL + "/api/data/v8.0/hms_supporttickets" + supportTicketId.replace("{", "(").replace("}", ")");
                var requestData = { "hms_assigntosystemuserid": systemUserId };

                HMS.CRMUtil.executeWebAPI(
                    "PATCH",
                    uri,
                    requestData,
                    function (data) {
                        // 刷新视图列表
                        Mscrm.Utilities.refreshCurrentGrid(Mscrm.EntityPropUtil.EntityTypeName2CodeMap["hms_supportticket"]);
                    },
                    function (data) {
                        debugger;
                        alert("分派工单出错," + data.message);
                    });
            })
            .fail(function (error) {
                // Do sth.
            });

17.刷新视图列表

Mscrm.Utilities.refreshCurrentGrid(Mscrm.EntityPropUtil.EntityTypeName2CodeMap["hms_supportticket"]);

18.判断当前表单是不是新建状态未保存过

var formType = formContext.ui.getFormType();
if (formType != 1) {
  //已经保存过了    
} else {
   //新建状态
}

19.触发字段onchange事件

formContextmaketaction.getAttribute(fieldname).fireOnChange()

20.设置iframe的url

var hisiframe = Xrm.Page.context.getClientUrl() + "/WebResources/hms_explain.html";
var iFramehis = formContextmaketaction.ui.controls.get("IFRAME_levelexplain");
iFramehis.setSrc(hisiframe);

21.自定义单选或多选lookup弹出窗口

/// <summary>
/// 功能:根据工程师角色推荐分派专员
/// </summary>
this.createAssignViewWithEngineerRole = function (supportTicketId) {
    // 当工单不满足分派条件 直接返回
    if (!HMS.SupportTicket.RibbonEvent.validateTicket(supportTicketId)) {
        return;
    }

    // 根据擅长业务查找FAE工程师
    var fetchData = {
        name: "分派专员"
    };
    var fetchXml = [
        "<fetch>",
        "  <entity name='systemuser'>",
        "    <attribute name='systemuserid' />",
        "    <attribute name='fullname' />",
        "    <attribute name='domainname' />",
        "    <link-entity name='systemuserroles' from='systemuserid' to='systemuserid' link-type='inner'>",
        "      <link-entity name='role' from='roleid' to='roleid' link-type='inner'>",
        "        <filter type='or'>",
        "          <condition attribute='name' operator='eq' value='", fetchData.name/*分派专员*/, "'/>",
        "        </filter>",
        "      </link-entity>",
        "    </link-entity>",
        "  </entity>",
        "</fetch>",
    ].join("");

    HMS.SupportTicket.RibbonEvent.createAssignViewForAssigner(fetchXml, supportTicketId);

}
/// <summary>
/// 功能:生成分派专员视图。
/// </summary>
this.createAssignViewForAssigner = function (fetchXml, supportTicketId) {
    debugger;
    //1. 定义视图唯一编号guid,可用guid工具生成,只要不重复即可。
    var viewId = "{00000000-0000-0000-0000-000000000002}";

    //2. 获取自定义查询实体的type code,避免同一个实体在不同系统中typecode不相同带来的问题
    var objectTypeCode = Mscrm.EntityPropUtil.EntityTypeName2CodeMap["systemuser"];

    //4. 构造自定义视图
    var layoutXML = "<grid name='resultset' object='" + objectTypeCode + "' jump='hms_name' select='1' icon='0' preview='0'>" +
        "<row name='result' id='systemuser'>" +
        "<cell name='fullname' width='150' />" +
        "<cell name='domainname' width='150' />" +
        "</row>" +
        "</grid>";

    var customerView = {
        Type: 0, //固定值0
        fetchXml: fetchXml,
        id: viewId,
        layoutXml: layoutXML,
        name: "分派专员",
        recordType: objectTypeCode
    };

    //5. 构造dialogOption
    var lookupOptions = {
        defaultEntityType: "systemuser",
        entityTypes: ["systemuser"],
        viewIds: [viewId],
        allowMultiSelect: false,
        defaultViewId: viewId,
        customViews: [customerView]
    };

    //6. 构造dialog调用参数
    Xrm.Utility.lookupObjects(lookupOptions)
        .then(function (result) {
            debugger;
            var domainName = JSON.parse(result[0].keyValues).domainname.value;
            var systemUserId = HMS.SupportTicket.RibbonEvent.getSystemUserIdByDomainName("'" + domainName + "'");

            var clientURL = Xrm.Page.context.getClientUrl();
            var uri = clientURL + "/api/data/v8.0/hms_supporttickets" + supportTicketId.replace("{", "(").replace("}", ")");
            var requestData = { "hms_assigntosystemuserid": systemUserId };

            HMS.CRMUtil.executeWebAPI(
                "PATCH",
                uri,
                requestData,
                function (data) {
                    // 刷新视图列表
                    Mscrm.Utilities.refreshCurrentGrid(Mscrm.EntityPropUtil.EntityTypeName2CodeMap["hms_supportticket"]);
                },
                function (data) {
                    debugger;
                    alert("分派工单出错," + data.message);
                });
        })
        .fail(function (error) {
            // Do sth.
        });

}

后台

1.创建数据库连接服务

 ClientCredentials clientCredent = new ClientCredentials();
            clientCredent.UserName.UserName = UserName + "@" + DomainName;
            clientCredent.UserName.Password = Password;
            Uri uri = new Uri(ServiceUri);
            IServiceManagement<IOrganizationService> sm = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(uri);
            IOrganizationService organizationService = new OrganizationServiceProxy(sm, clientCredent);
            OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(sm, clientCredent);

2.实体赋值

注意,此方法只能用来赋值,不能用来取值

 Entity entity = new Entity("salesorder", Guid.Parse("0745f62c-3acf-eb11-a13a-00505687c0be"));
            entity["hms_so"] = "1000005748";//SO
            entity["hms_sapstatus"] = "成功";//SAP状态
            organizationService.Update(entity);

3.查询数据(使用方法查询、关联查询)

            //先创建个返还申请明细的查询
            QueryExpression queryExpression = new QueryExpression("hms_retrunrequestorderdetail");
            //查询出全部列
            queryExpression.ColumnSet = new ColumnSet(true);
            //设置查询条件为固定ID的数据
            //queryExpression.Criteria.AddCondition("hms_retrunrequestorderid", ConditionOperator.Equal, target.Id);
            //关联上返还申请主表
            var linkEntity1 = queryExpression.AddLink("hms_retrunrequestorder", "hms_retrunrequestorderid", "hms_retrunrequestorderid");
            //判断主表状态为审批通过的
            linkEntity1.LinkCriteria.AddCondition("hms_status", ConditionOperator.Equal, 40/*审批通过*/);
            //查询出指定返还申请的所有明细
            var result = organizationService.RetrieveMultiple(queryExpression);
            //如果能查询到
            if (result != null && result.Entities != null)
            {
                //获取查询处的返还申请明细实体集合
                var returnRequestOrderDetails = result.Entities;
                //循环该集合
                foreach (var detail in returnRequestOrderDetails)
                {
                    if (detail.GetAttributeValue<EntityReference>("hms_salesorderexecutedetailid") == null)
                    {
                        continue;
                    }
                    //获取返还申请明细中关联的物料领用申请执行明细ID
                    var salesOrderExecuteDetailId = detail.GetAttributeValue<EntityReference>("hms_salesorderexecutedetailid").Id;
                    //定义一个返还申请明细的查询
                    queryExpression = new QueryExpression("hms_retrunrequestorderdetail");
                    //查询出所有列
                    queryExpression.ColumnSet = new ColumnSet(true);
                    //按指定的物料领用执行明细查询
                    queryExpression.Criteria.AddCondition("hms_salesorderexecutedetailid", ConditionOperator.Equal, salesOrderExecuteDetailId);
                    //返还数量不为空的
                    queryExpression.Criteria.AddCondition("hms_count", ConditionOperator.NotNull);
                    //关联上返还申请主表通过主表id
                    var linkEntity = queryExpression.AddLink("hms_retrunrequestorder", "hms_retrunrequestorderid", "hms_retrunrequestorderid");
                    //判断主表状态为审批通过的
                    linkEntity.LinkCriteria.AddCondition("hms_status", ConditionOperator.Equal, 40/*审批通过*/);
                    //查询出所有数据
                    result = organizationService.RetrieveMultiple(queryExpression);
                    if (result != null && result.Entities != null && result.Entities.Count > 0)
                    {
                        //计算出此物料领用明细关联出的所有返还申请明细返还数量的和
                        var totalReturnCount = result.Entities.Sum(s => s.GetAttributeValue<decimal>("hms_count"));
                        // 定义一个物料领用申请执行明细实体
                        Entity materialRequisitionOrder = new Entity("hms_salesorderexecutedetail", salesOrderExecuteDetailId);
                        //更新他的实际返还数量
                        materialRequisitionOrder["hms_actualreturnquantity"] = totalReturnCount;
                        organizationService.Update(materialRequisitionOrder);
                    }
                }
            }

4.常用查询(查询单条、多条)


查询单条
 Entity entity = service.Retrieve(ename, new Guid(eid), new ColumnSet(true));
查询多条
QueryExpression queryExpression = new QueryExpression()
                {
                    EntityName = "hms_salesorderdetail",
                    ColumnSet = new ColumnSet(true)
                };
                queryExpression.Criteria.AddCondition("hms_stockplace", ConditionOperator.Null);
                queryExpression.Criteria.AddCondition("hms_salesorderid", ConditionOperator.Equal, entity.Id);
                var orderDetailList = service.RetrieveMultiple(queryExpression);
                if (orderDetailList.Entities.Count > 0)
                {
                     throw new InvalidPluginExecutionException("销售合同明细库存地点不能为空!");
                }

5.使用fetch查询

5.1关联查询

var cancelApplyId = target.GetAttributeValue<EntityReference>("hms_cancelapplyid").Id;
                var fetchXml = $@"
                    <fetch>
                      <entity name='hms_company'>
                        <attribute name='hms_sapfactoryname' />
                        <link-entity name='salesorder' from='hms_companyid' to='hms_companyid' link-type='inner'>
                          <link-entity name='hms_cancelapply' from='hms_salesorderid' to='salesorderid' link-type='inner'>
                            <filter>
                              <condition attribute='hms_cancelapplyid' operator='eq' value='{cancelApplyId}'/>
                            </filter>
                          </link-entity>
                        </link-entity>
                      </entity>
                    </fetch>";

                FetchExpression fetchExpression = new FetchExpression(fetchXml);
                var result = service.RetrieveMultiple(fetchExpression);
                if (result != null && result.Entities != null && result.Entities.Count > 0)
                {
                    var company = result.Entities[0];
                    target["hms_factory"] = company.GetAttributeValue<string>("hms_sapfactoryname");
                }

5.2分组查询合并数量

var fetchXml = $@"
                        <fetch mapping='logical' aggregate='true' version='1.0'>
                          <entity name='hms_deliverydetail'>
                            <attribute name='hms_count' alias='sum_hms_count' aggregate='sum' />
                            <attribute name='hms_itemid' alias='group_itemid' groupby='true' />
                            <attribute name='hms_deliveryproductid' alias='group_deliveryproductid' groupby='true' />
                                <filter>
                                  <condition attribute='hms_deliveryid' operator='eq' value='{image.Id}'/>
                                </filter>
                          </entity>
                        </fetch>";
                    FetchExpression fetchExpression = new FetchExpression(fetchXml);
                    var result = service.RetrieveMultiple(fetchExpression);
                    if (result != null && result.Entities != null && result.Entities.Count > 0)
                    {
                        lineCount = result.Entities.Count;
                        workflowRequestTableRecords = new WorkflowRequestTableRecord[lineCount];

                        int k = 0;
                        foreach (var sourceEntity in result.Entities)
                        {
                            workflowRequestTableField = new WorkflowRequestTableField[10];

                            i = 0;
                            //交货单
                            workflowRequestTableField[i] = GetTableFields(workflowRequestTableField, "jhd", i);
                            string deliveryproductname = ((EntityReference)((AliasedValue)sourceEntity.Attributes["group_deliveryproductid"]).Value).Name;
                            workflowRequestTableField[i].fieldValue = deliveryproductname;

                            i++;
                            //物料编号
                            workflowRequestTableField[i] = GetTableFields(workflowRequestTableField, "wlbm", i);
                            string itemname = ((EntityReference)((AliasedValue)sourceEntity.Attributes["group_itemid"]).Value).Name;
                            workflowRequestTableField[i].fieldValue = itemname;

                            i++;
                            //物料描述
                            workflowRequestTableField[i] = GetTableFields(workflowRequestTableField, "wlms", i);
                            Guid itemid = ((EntityReference)((AliasedValue)sourceEntity.Attributes["group_itemid"]).Value).Id;
                            workflowRequestTableField[i].fieldValue = GetOABussinessValue(itemid, "hms_item", "hms_itemdescription", service);

                            i++;
                            //合计数量
                            workflowRequestTableField[i] = GetTableFields(workflowRequestTableField, "slhj", i);
                            string coun = ((AliasedValue)sourceEntity.Attributes["sum_hms_count"]).Value.ToString();
                            workflowRequestTableField[i].fieldValue = coun;

                            workflowRequestTableRecords[k] = new WorkflowRequestTableRecord();
                            workflowRequestTableRecords[k].workflowRequestTableFields = workflowRequestTableField;

                            k++;
                        }
                    }

6.通过多条件过滤数据,匹配到的更新,否则新增

ExecuteMultipleRequest multipleReq = new ExecuteMultipleRequest()
                {
                    Settings = new ExecuteMultipleSettings()
                    {
                        ContinueOnError = true,
                        ReturnResponses = true
                    },
                    Requests = new OrganizationRequestCollection()
                };

                Boolean failed = false;
                //Insert data into CRM
                if ((response.Subrc == 0) && zscrm009s.Length > 0)
                {
                    for (int i = 0; i < zscrm009s.Length; i++)
                    {
                        //t052 payTerm = payTerms[i];
                        var soldToPart = zscrm009s[i];

                        var businessPartnerNumber = soldToPart.Kunnr;
                        if (businessPartnerNumber.Length == 10 && businessPartnerNumber.StartsWith("0000"))
                        {
                            businessPartnerNumber = businessPartnerNumber.Substring(4);
                        }

                        //售达方联合主键
                        KeyAttributeCollection keyCollect = new KeyAttributeCollection();
                        keyCollect.Add("hms_name", soldToPart.Kunnr); // SAP客户编码
                        keyCollect.Add("hms_salesorganizationnumber", soldToPart.Vkorg);// 销售组织编号
                        keyCollect.Add("hms_sapdistributionchannel", soldToPart.Vtweg);// 分销渠道
                        keyCollect.Add("hms_productgroup", soldToPart.Spart);// 产品组

                        Entity soldToParty = new Entity("hms_sapsoldtoparty", keyCollect);
                        // SAP客户编码
                        soldToParty["hms_name"] = soldToPart.Kunnr;
                        // 销售组织编号
                        soldToParty["hms_salesorganizationnumber"] = soldToPart.Vkorg;
                        // 分销渠道
                        soldToParty["hms_sapdistributionchannel"] = soldToPart.Vtweg;
                        // 产品组
                        soldToParty["hms_productgroup"] = soldToPart.Spart;

                         组织名称
                        soldToParty["hms_salesorganizationid"] = RetrieveSalesOrg(serviceProxy, soldToPart.Vkorg);
                         分销渠道
                        soldToParty["hms_distributionchannels"] = DistributionChannels(soldToPart.Vtweg);
                         合作伙伴功能
                        soldToParty["hms_partnerfunction"] = soldToPart.Parvw;
                         组织名称
                        soldToParty["hms_orgname"] = soldToPart.Name1;


                        //同步销售视图删除标识 20210810 yhx
                        string LoevmV = soldToPart.LoevmV;
                        soldToParty["hms_loevmv"] = string.IsNullOrEmpty(LoevmV) ? true : false;
                        //同步财务视图删除标识 
                        string Loevm = soldToPart.Loevm;
                        soldToParty["hms_loevm"] = string.IsNullOrEmpty(Loevm) ? true : false;


                        UpsertRequest req = new UpsertRequest()
                        {
                            Target = soldToParty
                        };

                        multipleReq.Requests.Add(req);

                        if (multipleReq.Requests.Count >= 1000)
                        {
                            //Insert/Update payment term into CRM
                            mulresponse = (ExecuteMultipleResponse)serviceProxy.Execute(multipleReq);
                            if (mulresponse.IsFaulted || failed) 
                            {
                                failed = true;
                                results[1] = "获取SAP售达方数据成功,更新至CRM时出错,请重试或联系系统管理员。";
                            }
                            else
                            {
                                results[1] = "获取SAP售达方数据成功并已同步至CRM售达方中。";
                            }

                            multipleReq.Requests.Clear();

                        }
                    }

                    if (multipleReq.Requests.Count > 0)
                    {
                        //Insert/Update payment term into CRM
                        mulresponse = (ExecuteMultipleResponse)serviceProxy.Execute(multipleReq);
                        if (mulresponse.IsFaulted || failed)
                        {
                            failed = true;
                            results[1] = "获取SAP售达方数据成功,更新至CRM时出错,请重试或联系系统管理员。";
                        }
                        else
                        {
                            results[1] = "获取SAP售达方数据成功并已同步至CRM售达方中。";
                        }

                    }

                }
                else
                {
                    results[1] = "未获取到满足条件的SAP售达方数据。";
                }

            }

7.错误提示

throw new InvalidPluginExecutionException("非草稿或退回状态下不能删除");

8.共享数据

/// <summary>
        /// 共享记录(读与写)  需要添加引用Microsoft.Crm.Sdk.proxy;
        /// using Microsoft.Crm.Sdk.Messages;
        /// </summary>
        /// <param name="teamOrSystem">要共享给用户或者团队</param>
        /// <param name="record">要共享的记录</param>
        private static void Grant(IOrganizationService service, EntityReference teamOrSystemUser, EntityReference record)
        {
            GrantAccessRequest grantAccessRequest = new GrantAccessRequest
            {
                Target = record,
                PrincipalAccess = new PrincipalAccess
                {
                    Principal = teamOrSystemUser,
                    AccessMask = AccessRights.WriteAccess | AccessRights.ReadAccess | 
                }
            };
            service.Execute(grantAccessRequest);
        }
//撤销共享

 var revokeUserAccessReq = new RevokeAccessRequest
                {
                    Revokee = new EntityReference("LogicalName",Guid),//需要撤销共享的团队
                    Target = new EntityReference("LogicalName", Guid),//需要撤销的目标实体
                };
   SysService.Execute(revokeUserAccessReq);

9.新增数据


查询单条
 Entity entity = service.Retrieve(ename, new Guid(eid), new ColumnSet(true));
查询多条
QueryExpression queryExpression = new QueryExpression()
                {
                    EntityName = "hms_salesorderdetail",
                    ColumnSet = new ColumnSet(true)
                };
                queryExpression.Criteria.AddCondition("hms_stockplace", ConditionOperator.Null);
                queryExpression.Criteria.AddCondition("hms_salesorderid", ConditionOperator.Equal, entity.Id);
                var orderDetailList = service.RetrieveMultiple(queryExpression);
                if (orderDetailList.Entities.Count > 0)
                {
                     throw new InvalidPluginExecutionException("销售合同明细库存地点不能为空!");
                }

10.修改数据

  string str = "D2B83152-EC20-EC11-A13C-00505687C0BE,DFDBB45A-EC20-EC11-A13C-00505687C0BE";
                string[] arr = str.Split(',');
                for (int i = 0; i < arr.Length; i++)
                {
                    Entity entity = new Entity("hms_delivery", Guid.Parse(arr[i]));
                    entity["hms_tallystatus"] = new OptionSetValue(50);
                    entity["hms_deliverystatus"] = new OptionSetValue(50);
                    organizationService.Update(entity);
                }

11.执行多条数据

//批量执行可以是新增、修改,或者判断没有就新增否则修改分别对应不同的Request
//CreateRequest、UpdateRequest、UpsertRequest
//值得注意的是UpsertRequest需要指定对比的key字段
//Entity deliveryProduct = new Entity("hms_deliveryproduct", "hms_name", sapDelivery.VBELN);
//如果是UpdateRequest那么要赋值id
 ExecuteMultipleRequest multipleReq = new ExecuteMultipleRequest();
 multipleReq = new ExecuteMultipleRequest()
 {
     Settings = new ExecuteMultipleSettings()
     {
         ContinueOnError = true,
         ReturnResponses = true
     },
     Requests = new OrganizationRequestCollection()
 };
foreach (var deliveryProduct in deliveryProductEntities.Entities)
{
    Entity entity = new Entity("hms_deliveryproduct", deliveryProduct.Id);
    entity["hms_isinsertdliverydata"] = true;
    UpdateRequest req = new UpdateRequest()
    {
        Target = entity
    };
    multipleReq.Requests.Add(req);
}

//Insert/Update product into CRM
ExecuteMultipleResponse mulresponse = new ExecuteMultipleResponse();
try
{
    mulresponse = (ExecuteMultipleResponse)serviceProxy.Execute(multipleReq);
}
catch (Exception ex)
{
    results[1] = "更新交货单的交货标识字段失败:: " + ex.Message;
}

12.人员赋予角色

  AssociateEntitiesRequest associateEntitiesRequest = new AssociateEntitiesRequest()
  {
            RelationshipName = "多对多关系名称"
  };
  associateEntitiesRequest.Moniker1 = new EntityReference("systemuser", new Guid(entityid));
                    associateEntitiesRequest.Moniker2 = new EntityReference("role", new Guid(item));

                    OrganizationService.Execute(associateEntitiesRequest);

13. 团队成员增删管理

//新增成员方法
public void AddUsersToTeam(IOrganizationService serviceadmin,EntityReference team, params EntityReference[] users)
{
    var req = new AddMembersTeamRequest
    {
        TeamId = team.Id,
        MemberIds = users.Select(x => x.Id).ToArray()
    };
    serviceadmin.Execute(req);
}
//删除成员方法
private void RemoveMember(IOrganizationService orgService, EntityReference team,Entity systemUser)
{
    var request = new RemoveMembersTeamRequest
    {
        TeamId = team.Id,
        MemberIds = new[] { systemUser.Id }
    };
    orgService.Execute(request);
}

数据库

1.获取表单下拉框选项值的Text

CREATE FUNCTION [dbo].[fn_GetOptionSetValueName]  
(  
@entity_name nvarchar(50),  
@colume_name nvarchar(50),  
@attributevalue int  
)   
RETURNS  varchar(50)  
  
AS  
BEGIN;  
declare @return_value varchar(100);  
  
SET @return_value =  
(  
SELECT Value  
        FROM dbo.StringMap   
        WHERE AttributeName = @colume_name  
  and AttributeValue = @attributevalue  
        AND ObjectTypeCode =  
              (  
     SELECT distinct ObjectTypeCode  
                  FROM MetadataSchema.Entity  
                  WHERE Name = @entity_name  
              )    
     );  
     RETURN @return_value;  
END  
  
  

系统运维

1.设置系统登录超时时间

Get-ADFSRelyingPartyTrust
Set-ADFSRelyingPartyTrust -Targetname "CRM IFD Replaying Party" -TokenLifetime 1440

2.在登录页添加修改密码

参考以下两个,注意ADFS的地址,不是系统的地址端口

Dynamics CRM修改密码界面_dynimiccrm修改密码-CSDN博客

添加登录页面描述 | Microsoft Learn

3.登录页面的自定义,如隐藏Logo等

AD FS 用户登录自定义 | Microsoft Learn

4.其他

ADFS 3.0登录页面不用输入域名的实现方法_adfs 域名 免-CSDN博客

如何关闭ad服务器密码策略 • Worktile社区

工具使用

1.下载地址

常用的工具有开发工具和调试工具

开发工具 plugin工具下载地址

Walkthrough: Register a plug-in using the plug-in registration tool | Microsoft Docs

调试工具有以下两种,需要从谷歌市场中下载(需要翻墙)

 按钮开发工具为Ribbon Workbench

Develop 1 Ltd | Ribbon Workbench for Dynamics 365 & Dynamics CRM

2.Plugin监听执行顺序

PreValidation 数据未发生变化之前

PreOperation 数据未发生变化之前

PostOperation 数据发生变化之后,此时使用组织服务查询数据得到的是变化后的数据,删除操作在此阶段无法查询到数据

每个阶段之间不会互相影响,即PreValidation中执行的操作即使PreOperation中报错也会生效,但是同一个实体在不同的Step的同一个事件中,只要有一个Step报错其他Step中的操作就会回滚

相同的事件,可以通过 Excution Order来设置执行的顺序

3.Plugin监听事件Message

Create 创建

Update 更新

Delete 删除

Assign 分派

GrantAccess 共享

ModifyAccess 修改共享权限

RevokeAccess 移除共享

分派会触发Assign和Update(如果设置了监听ownerid字段)

开发步骤

  1. 创建实体
  2. 新建字段
  3. 新建窗体
  4. 新建js
  5. 注册按钮
  6. 新建类库
  7. 在VS中安装

D365 Developer Extensions扩展

  1. 在VS中安装nuget工具Microsoft.CrmSdk.CoreAssemblies
  2. 新建CS文件
  3. 注册Assembly 注意需要给类库新增签名hms.snk否则会在创建时报错

  1. 在窗体中引用js需要主要的事

别忘了引用hms_/scripts/CRMUtil.js

注意事项

1.在用rest查询数据时,一定注意实体名要加s,id字段要写成_idfield_value的样式

字段联动开发逻辑

fun1
可编辑字段赋值
fun2
显示控制
fun3
不可编辑字段赋值


//所有表单打开控制字段显示隐藏
fun2

//复制单据,第一次打开单据控制,仅用于复制单据有字段联动触发存在可编辑字段带出值为最新
formtype!=1&&((orderStatuts == 10 || orderStatuts == 60) && hms_createtype == 2 && hms_iffirstopen)
fun1

//字段联动存在不可编辑字段赋值,若希望草稿状态单据打开时保持带出字段信息最新
status==10 or 60
fun3

//字段change事件所有方法都触发
fieldchange(changefun)

如果不需要带出最新数据,只需要写两个方法,一个是字段控制显示逻辑,一个是控制字段赋值逻辑

changefun(){
	fun1
	fun2
	fun3
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值