Can't close Incident through Web API client side - javascript

On Dynamics 365, we are trying to close incidents using the client side Web API.
After looking at the doc (in C#), we understand that we first need to create a IncidentResolution activity, which we did successfully.
However, we don't understand how to fully close the Incident entity then.
I assume we need to update the record's stateCode and statusCode.. However, if I do so, ajax always return a 500 error.
Other updates are working fine.
Is there anything that we're missing here ?
var entity = {};
entity.statecode = 1; // Resolved
entity.statuscode = 5; // Problem Solved
entity.title = "Title of my case";
var req = new XMLHttpRequest();
req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/incidents(Case's guid)", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
//Success - No Return Data - Do Something
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));

You have to use CloseIncident Action & POST method to do this. It's not a simple update request by using PATCH method, basically case closure will create an Incident Resolution entity record.
Normally I will compose the request using CRM REST builder, even that snippet is not executing successfully in this case. The complete working code example:
var incidentresolution = {
"subject": "Put Your Resolve Subject Here",
"incidentid#odata.bind": "/incidents(<GUID>)", //Replace <GUID> with Id of case you want to resolve
"timespent": 60, //This is billable time in minutes
"description": "Additional Description Here"
};
var parameters = {
"IncidentResolution": incidentresolution,
"Status": -1
};
var context;
if (typeof GetGlobalContext === "function") {
context = GetGlobalContext();
} else {
context = Xrm.Page.context;
}
var req = new XMLHttpRequest();
req.open("POST", context.getClientUrl() + "/api/data/v8.2/CloseIncident", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
//Success - No Return Data - Do Something
} else {
var errorText = this.responseText;
//Error and errorText variable contains an error - do something with it
}
}
};
req.send(JSON.stringify(parameters));
Reference

Related

CRM custom activity do not return output argument

I have written a custom activity as below,
namespace Tu.Crm.Packages.WorkFlows
{
public sealed class VersionFinder : CodeActivity
{
[Output("VersionDate")]
public OutArgument<string> VersionDate { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
try
{
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
VersionDate.Set(executionContext, "1#22/01/2019");
}
catch (FaultException<OrganizationServiceFault> e)
{
// Handle the exception.
throw new InvalidPluginExecutionException("Some error occurred/Proxy service unreachable" + e.StackTrace);
}
}
}
}
I am trying to call this activity from JavaScript.
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_versionfinderc2dcf0b12782eb11814500155de400c4", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
Xrm.Utility.alertDialog(this.ResponseXML);
} else {
Xrm.Utility.alertDialog(this.ResponseXML);
}
}
};
req.send();
However, it is not returning any data. What could be wrong?
I never tried calling custom workflow activity directly in js using web api, and its not usual to do AFAIK. The recommended way is to convert this into a custom action and call it in js web api.
If you want to keep this CWA, then use it in an UI workflow and execute the WF from js web api. You can use CWA in custom action too.

How to call Actions from Javascript Microsoft Dynamics

I have a requirement to call a Action Process from Javascript.
My Action Accept 2 Input Parameters and 1 output Param. Below is the screenshot of my Action
I have a textField in my Form, and on it's onChange event I'm calling this CallAction Method. Below is the JavaScript
function CallAction() {
var actionName = "taqi_getPrice";
var actionParameters = {
"base": "USD",
"TotalPrice": "200"
};
var actionResponse = activateCustomAction(actionName, actionParameters);
}
function activateCustomAction(actionName, actionParams) {
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_getPrice", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
alert('Success');
} else {
alert('fail');
//Xrm.Utility.alertDialog(this.statusText);
console.log(this);
}
}
};
req.send(JSON.stringify(actionParams));
}
When running this script I'm getting the following error in chrome console
POST https://techgulf.crm4.dynamics.com/api/data/v9.0/taqi_getPrice 404
Sometime it also says
Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers
Well I created Exact same Action as you mentioned in your screenshot, Except Entity I used is Account. I used below code to fire Action and it did worked for me without any issue and returned the value as expected.
May be for Testing you could provide static Guid and see how you get the result.
var parameters = {};
parameters.base = "123";
parameters.TotalPrice = "222";
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.1/accounts(DC86C293-CA4F-E911-A82F-000D3A385A1C)/Microsoft.Dynamics.CRM.crmp_TestAction2", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var results = JSON.parse(this.response);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(parameters));
Change the below line
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_getPrice", false);
like this one below:
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/taqi_cars(" + Id + ")/Microsoft.Dynamics.CRM.taqi_getPrice", false);
Basically we need to pass name of the Entity Set with id of the record
followed by name of the action appended with Microsoft.Dynamics.CRM.
In case of global action, we just need the
Microsoft.Dynamics.CRM.<<ActionName>>.
Reference
Looks like you need a synchronous Action call execution (as you’re using false in req.open) otherwise you can use Xrm.WebApi.online.execute which is always Asynchronous. Read more

"Resource not found for the segment *publisherguid*" in XMLHTTP query to create solution in the CRM

I'm trying to create a solution in the CRM with javascript.
My code is a webresource that I get through a Ribbon I created with "Ribbon Workbench 2016". These things work very good, but when I try to pass the data I get from user ( from a form ) to the CRM, I get the error in the title.
At first I thought the problem was that the guid was all in lower case, so I converted it in upper case. Nothing changed.
Then I tried using the friendlyname of the publisher instead of the guid.
Nothing changed.
Al last, I was frustrated, so I used an empty string, and the error changed from the one in the title, to "linkPath should have 2 segments". Guess it was a progress...but still have no idea what the real error might be.
What am I doing wrong? Is it right to treat the solution as an entity an create it that way? Is there a better way?
PS: The query was generated with CRM Rest Builder
var entity = {};
entity.friendlyname = $("#solutionForm").dxForm("instance").getEditor("Friendly name").option("value");
entity.uniquename = $("#solutionForm").dxForm("instance").getEditor("Unique name").option("value");
entity.version = $("#solutionForm").dxForm("instance").getEditor("Version").option("value");
entity["publisherid#odata.bind"] = keyValueContainerForPublishers[($("#solutionForm").dxForm("instance").getEditor("Publisher").option("value"))]; //contains guid of selected publisher
entity["configurationpageid#odata.bind"] = "";
entity.description = $("#solutionForm").dxForm("instance").getEditor("Description").option("value");
entity.solutionid = newGuid(); //create unique guid
entity.solutionpackageversion = null;
entity.solutiontype = 0;
var req = new XMLHttpRequest();
req.open("POST", window.parent.opener.Xrm.Page.context.getClientUrl() + "/api/data/v8.2/solutions", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
} else {
window.parent.opener.Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));
Alright below Webapi query I tried for creating solutiona and it did worked form me.
Few points to take care of
version should be someting like 1.0 or 2.0 or so. only 1 or 2 will not work
Publisher, If you compare your code and my code it should be "publishers" and not "publisher"
SolutionID you don't have to mention it will automatically create
I did not used configuraitonPageID and solutionPackageVersion for now.
Taking care of above things did created a solution for me.
var entity = {};
entity.friendlyname = "Test solution from WebAPI";
entity.uniquename = "TestSolutionFromWebAPI";
entity.version = "1.0";
entity["publisherid#odata.bind"] = "/publishers(6007BA03-EE7A-4CA1-A146-7EB0044E504F)";
entity.description = "This is test solution form webapi";
entity.solutiontype = 0;
var req = new XMLHttpRequest();
req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.1/solutions", false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function() {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 204) {
var uri = this.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var newEntityId = matches[1];
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send(JSON.stringify(entity));

BAD REQUEST When making an AJAX CALL: This.readyState is undefined

I wrote a function that fetches the guid of a lookup field and uses that to make an AJAX call. This is the the call that I made:
fetchOptionSet: function (executionContext) {
var formContext = executionContext.getFormContext(); //get form context
var client = Xrm.Page.context.getClientUrl(); //get client url
var childId = formContext.getAttribute("new_childid").getValue()[0].id;
var child = childId.replace(/[{}]/g, "");
var contract;
var req = new XMLHttpRequest();
req.open("GET", client + `/api/data/v8.2/new_childallergieses(${child})?$select=_new_childid_value`, true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var _new_childid_value = result["_new_childid_value"];
contract = _new_childid_value.replace(/[{}]/g, "");
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
However, I get a bad request every time that the script runs. I need the guid returned by the call (contractid) to make another ajax call! The uri is fine,I tested the link in the browser and it returns the contractid that I want.
First issue Bad request can be solved by replacing GUID value childId for any {}.
Second issue, this is Ajax call which is asynchronous by mentioning true in req.open, hence you may have some other issue with request uri. That’s why readyState is undefined.
Try this. Take your uri & paste in browser address bar to see any clear error.
http://test.crm.dynamics.com/api/data/v8.2/new_childallergieses(guid)?$select=_new_childid_value
Changed from Asychronous to Sychronous and all of a sudden it worked!
var path_one = Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_childallergieses(" + child + ")?$select=_new_childid_value";
req.open("GET", path_one , false);
I did some investigating and realized that the function is set to execute on load, and sending an asynchronous call on load gives a bad request.

What does readyState ==1 means?

I am using this below function to fetch the product number for a particular productid.
function GetQuickCode(){
var material = Xrm.Page.getAttribute("one_materialid").getValue();
var id = material[0].id;
id=id.replace("{","").replace("}","");
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber", true);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(this.response);
var productnumber = result["productnumber"];
Xrm.Page.getAttribute("one_quickcode").setValue(productnumber.Value);
} else {
Xrm.Utility.alertDialog(this.statusText);
}
}
};
req.send();
}
this function is returning readyState==1 which is why I am unable to find the value of product number. Also the response value does not contain anything. Can anyone tell me if I am wrong somewhere.
Try to debug your code in a few steps to find the problem.
First replace this line of code
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber", true);
by
var url= Xrm.Page.context.getClientUrl() + "/api/data/v8.2/products("+id+")?$select=productnumber";
console.log(url);
req.open("GET", url, true);
Does URL look correct?
Does it return correct result if you open directly in your browser?
If it works, you can continue further. If not, you need to fix the URL. You can start by removing parts from the end of the URL. Also, what is your CRM version? Is it 8.2 (Dynamics 365)?
Second, by using debug mode, inspect object this, especially attributes response and responseText, whether they contains some message.
Third, in F12 tool inspect the request and response. The tab is called Net or Network depending on browser. There can be many items. Clear the list before running your code. Look there what happened, what is returned for your request.

Categories