UNPKG

crm-sdk

Version:

Javasript Software Development Kit for Microsoft Dynamics CE Web API

570 lines (501 loc) 15.3 kB
## Entity tutorial ## 1) Entity Entity api can be accessed like WebAPI. ```javascript //app.js var CRMSDK = window.CRMSDK; var WebAPI = CRMSDK.WebAPI; var Entity = CRMSDK.Entity; ``` ```javascript import {Entity} from "crm-sdk"; ``` ```javascript var CRMSDK = require("crm-sdk"); //umd var Entity = CRMSDK.Entity; ``` ## 2) Entity ## 2.1) Entity.get Entity.get has three arguments: * logicalName * id * query (see odata chapter) ```javascript Entity.get(logicalName, id, query).then(function (account) { console.log(account.accountid); }); ``` ### 2.1.1) Entity.get using id ```javascript Entity.get("account", "475b158c-541c-e511-80d3-3863bb347ba8").then(function (account) { if (account) { console.log("Entity.get 'acount' by id " + account.emailaddress1); } }); ```` ### 2.1.2) Entity.get using direct filters ```javascript Entity.get("account", null, { emailaddress1: "Oeha@Dys.nl", statecode: 0 }).then(function (account) { if (account) { console.log("Entity.get 'acount' " + account.emailaddress1); } }); ``` ### 2.1.3) Entity.get using filters definition Result is exactly as example above, but operators can be different. Filter type can be "and" or "or". ```javascript Entity.get("account", null, { filters: [/*see odata chapter*/] }).then(function (account) { if (account) { console.log("Entity.get 'acount' " + account.emailaddress1); } }); ``` ## 2.2) Entity.query Entity.query has two arguments: * logicalName * query (see odata chapter) ```javascript Entity.query(logicalName, query).then(function (accounts) { //logic here }); ``` ### 2.2.1) Entity.query using direct filters ```javascript Entity.query("account", { emailaddress1: "test@dys.nl", statecode: 0 }).then(function (accounts) { accounts.forEach(function (account, index) { console.log("Entity.query 'account' " + account.emailaddress1 + " at " + index); }); }); ``` ### 2.2.2) Entity.query using filters definition ```javascript Entity.query("account", { filters: [{ type: "and", conditions: [{ attribute: "emailaddress1", operator: "eq", value: "test@dys.nl" }, { attribute: "statecode", operator: "eq", value: 0 }] }] }).then(function (accounts) { accounts.forEach(function (account, index) { console.log("Entity.query 'account' " + account.emailaddress1 + " at " + index); }); }); ``` ## 2.3) Create Entity.create has two arguments: * logicalName * data ```javascript Entity.create(logicalName, data).then(function (account) { //logic here }); ``` ### 2.3.1) Create example ```javascript Entity.create("account", { paymenttermscode: 4, statecode: 0, emailaddress1: "created@dys.nl" }).then(function (account) { console.log("entity.create 'acount' " + account.emailaddress1); }); ``` ## 2.4) Entity.fetch Entity.fetch has three arguments: * logicalName * fetchXml ```javascript Entity.fetch(logicalName, fetchXml).then(function (entities) { //logic here }); ``` ## 2.5) Entity.savedQuery ```text Enterprise version only ``` Entity.savedQuery has two arguments: * logicalName * queryName ```javascript Entity.savedQuery(logicalName, queryName).then(entities => { //logic here }); ``` ```javascript Entity.savedQuery("account", "Active Accounts").then(accounts => { //logic here }); ``` ## 2.6) Entity.userQuery ```text Enterprise version only ``` Entity.userQuery has two arguments: * logicalName * queryName ```javascript Entity.userQuery(logicalName, queryName).then(entities => { //logic here }); ``` ```javascript Entity.userQuery("account", "HelloWorld").then(accounts => { //logic here }); ``` ## 2.7) Entity.count Entity.count count has one argument: * logicalName ```javascript Entity.count(logicalName).then(function (nrOfEntities) { //logic here }); ``` ## 2.8) Bind For expanded(Lookup) Attributes it's not possible to assign a new value like on normal Attributes. A bind is the equivalent for this. Be aware that unbinding is not implemented yet, so removing a binding is not possible. When there are multiple targets, the third argument of the bind method is the target. ```javascript Entity.get("account", null, { emailaddress1: "Oeha@Dys.nl", statecode: 0, select: ["accountid", "name", "emailaddress1"], expand: [{ attribute: "primarycontactid", select: ["contactid", "fullname"] }] }).then(function (account) { if (account) { console.log("Entity.get 'acount' " + account.emailaddress1); console.log("Entity.get 'acount' " + account.primarycontactid.contactid); account.bind("primarycontactid", "67a6e5b9-88df-e311-b8e5-6c3be5a8b200").then(function () { console.log("Entity.get 'acount' " + account.primarycontactid.contactid); }); } }); ``` ## 2.9) Save Saving the entity can be done by invoking the save method. ```javascript Entity.get("account", { emailaddress1: "test@dys.nl", statecode: 0 }).then(function (account) { if (account) { console.log("entity.save 'acount' " + account.emailaddress1); account.emailaddress1 = "changed@dys.nl"; account.save().then(function () { console.log("entity.save 'acount' " + account.emailaddress1); }); } }); ``` ## 2.10) Delete Deleting an entity can be done by invoking the delete method. ```javascript Entity.get("account", { emailaddress1: "test@dys.nl", statecode: 0 }).then(function (account) { if (account) { console.log("entity.save 'acount' " + account.emailaddress1); account.emailaddress1 = "changed@dys.nl"; account.delete().then(function () { console.log("entity.delete 'acount' " + account.emailaddress1); }); } }); ``` ## 2.11) Entity.instantiate Entity.instantiate has two arguments: * data * logicalName It will instantiate the Entity local. ### 2.11.1) Instantiate example ```javascript Entity.instantiate({ paymenttermscode: 4, statecode: 0, emailaddress1: "instantiate@dys.nl" }, "account").then(function (account) { console.log("entity.instantiate 'acount' " + account.emailaddress1); account.save(); // create the account in CRM. }); ``` # 3) OData The query arguments contain OData elements in json format. ## 3.1) $select The 'select' is an array of attributes of the entity. If no 'select' is specified, all Attributes of the logicalName will be selected. This may cause performance issues. ```javascript Entity.query("account", { select: ["accountid"] }).then(function (data) { console.log(data.value[0].accountid); }); ``` When adding a Lookup in the select, the value will be an Object having LogicalName, Name, Id. Normally odata skips Lookup attributes in the select, but the WebAPI.js will resolve to LogicalName, Id, Name. ```javascript Entity.get("systemuser", id, { select: ["systemuserid", "businessunitid"] }).then(function (systemuser) { if (systemuser) { console.log("Entity.get 'systemuser' " + systemuser.systemuserid); console.log("Entity.get 'systemuser.businessunitid.LogicalName' " + systemuser.businessunitid.LogicalName); console.log("Entity.get 'systemuser.businessunitid.Id' " + systemuser.businessunitid.Id); console.log("Entity.get 'systemuser.businessunitid.Name' " + systemuser.businessunitid.Name); } }); ``` ## 3.2) $expand The 'expand' is an array of Lookup attributes having a nested select. A nested expand is not possible due to restrictions on CRM side. ```javascript Entity.query("account", { select: ["accountid"], expand: [{ attribute: "businessunitid", select: ["name"] }] }).then(function (data) { console.log(data.value[0].businessunitid.name); }); ``` When an expand has no 'select', all attributes will be taken. ```javascript //The primarycontactid will be expanded by all Contact Attributes. Entity.get("account", null, { emailaddress1: "Oeha@Dys.nl", statecode: 0, select: ["accountid", "name", "emailaddress1"], expand: ["primarycontactid"] }).then(function (account) { if (account) { console.log("Entity.get 'acount' " + account.emailaddress1); console.log("Entity.get 'acount' " + account.primarycontactid.fullname); } }); ``` ## 3.3) $orderby The 'orders' is an array of configurations of attribute and descending boolean. ```javascript entity.query("account", { select: ["accountid"], orders: [{ attribute: "accountid", descending: true }] }).then(function (data) { console.log(data.value[0].accountid); }); ``` ## 3.4) $filter The 'filters' is an array of configurations of filter type and conditions. Filters can also be nested to support 'grouping'. See https://msdn.microsoft.com/en-us/library/gg334767.aspx#bkmk_filter for possible operator values. ```javascript entity.query("account", { select: ["accountid"], filters: [{ type: "or", conditions: [{ attribute: "paymenttermscode", operator: "eq", value: 4 }, { attribute: "industrycode", value: 8 }], filters: [{ type: "and", conditions: [{ attribute: "statecode", value: 0 }] }] }] }).then(function (data) { console.log(data.value[0].accountid); }); ``` Instead of 'filters' it's also possible to use direct-filters, which are always 'and' conditions using 'eq' condition: ```javascript entity.query("account", { paymenttermscode: 4, statecode: 0, select: ["accountid"] }).then(function (data) { console.log(data.value[0].accountid); }); ``` ## 3.5) Orders Ordering is supported via orders attribute. Each order config has 'attribute' and 'descending'. To order Attributes, please use the 'expand'. This is equal to the web-API $orderby. ```javascript Entity.query("account", { emailaddress1: "Oeha@Dys.nl", statecode: 0, select: ["accountid", "name", "emailaddress1"], orders: [{ attribute: "accountid", descending: true }] }).then(function (account) { if (account) { console.log("Entity.get 'acount' " + account.emailaddress1); } }); ``` ## 3.6) maxpagesize This will add the odata.maxpagesize=x as header in the request. ```javascript Entity.query("account", { maxpagesize: 3 }).then(function (accounts) {}); ``` ## 3.7) top This will add $top in the request. ```javascript Entity.query("account", { top: 3 }).then(function (accounts) {}); ``` # 4) Account Account is a sub-class of Entity. It can be included in your application the same way. The Account will ease programming. ## 4.1) Definition Instead of ```javascript Entity.query("account", query).then(function (accounts) {}); Entity.get("account", id, query).then(function (account) {}); ``` the following can be used: ```javascript Account.query(query).then(function (accounts) {}); Account.get(id, query).then(function (account) {}); ``` ## 4.2) Active accounts The Account has a getter for the activeFilter and a method to get active accounts. The method is the easiest one, but also good to know that there is a filter. The Account activeFilter: ```javascript Account.query({ filters: [Account.activeFilter], select: ["accountid", "emailaddress1"] }).then(function (accounts) {}); ``` The Account getActiveAccounts method: ```javascript Account.getActiveAccounts({ select: ["accountid", "emailaddress1"] }).then(function (accounts) { accounts.forEach(function (account, index) { console.log("Entity.query 'account' " + account.emailaddress1 + " at " + index); }); }); ``` # 5) Systemuser Systemuser is a sub-class of Entity. It can be included in your application the same way. The Systemuser will ease programming. ## 5.1) userId The Systemuser has a getter for the userId. Instead of ```javascript var userId = window.Xrm.Page.context.getUserId(), trimmedId = userId.slice(1, userId.length - 1); //No curly-braces Systemuser.get(null, { systemuserid: trimmedId, select: ["systemuserid"] }).then(function (systemuser) { console.log("Systemuser.get current 'systemuser' " + systemuser.systemuserid); }); ``` the following can be used: ```javascript Systemuser.get(null, { systemuserid: Systemuser.userId, //No curly-braces select: ["systemuserid"] }).then(function (systemuser) { console.log("Entity.get current 'systemuser' " + systemuser.systemuserid); }); ``` ## 5.2) Current Systemuser The Systemuser has a getter for the currentFilter and a method to get the current systemuser. The method is the easiest one, but also good to know that there is a filter. The Systemuser currentFilter: ```javascript Systemuser.get(null, { filters: [Systemuser.currentFilter], select: ["systemuserid"] }).then(function (systemuser) { console.log("Entity.get current 'systemuser' " + systemuser.systemuserid); }); ``` The Systemuser getCurrent method: ```javascript Systemuser.getCurrent({ select: ["systemuserid"] }).then(function (systemuser) { console.log("Entity.get 'systemuser' " + systemuser.systemuserid); }); ``` # 6) Annotation Annotation is a sub-class of Entity. It can be included in your application the same way. The Annotation will ease programming. ## 6.1) parseFile ```javascript Annotation.parseFile(annotation).then(function (file) {}); ``` ## 6.2) parseAnnotation ```javascript var id = window.Xrm.Page.data.getEntity().getId(); var logicalName = window.Xrm.Page.data.getEntity().getEntityName(); Annotation.parseAnnotation(file, id, logicalName).then(function (annotation) { annotation.save().then(function () {}); }); ``` # 7) Webresource Webresource is a sub-class of Entity. It can be included in your application the same way. The Webresource will make it easy to modify webresources. Publishing is included in the save (save === upload + publish). ```javascript import {Webresource} from "crm-sdk"; // update example let webresource = Webresource.get(null, { name: webresourceName, select: ["name", "webresourcetype"] }).then(function (webresource) { webresource.content = "<base64 string here>"; webresource.save().then(function () { // saved and published }); }); // insert example webresource = new Webresource({ content: "<base64 string here>", name: "<filename>", displayname: "<displayname>" }); webresource.solutionUniqueName = "<solution name>"; // otherwise "Active" solution will be taken webresource.save().then(function () { // saved and published }); ```