Working in Dynamics 365 doing plugin development was problematic yesterday. I've seen more than one occasion now where I can't get a plugin to work properly and there is no obvious reason why. It turned out that uninstalling and reinstalling the plugin profiler solution fixed the issue with no code change.
The profiler must be caching something......
I hope this helps someone else and I am not the only person seeing this wonky behavior!
Showing posts with label CRM Online. Show all posts
Showing posts with label CRM Online. Show all posts
Friday, August 25, 2017
Plugin Profiler Causing Problems
Labels:
.NET,
CRM Online,
Dynamics 365,
Microsoft Dynamics CRM,
Plug-in,
Plugins
Wednesday, May 27, 2015
Microsoft Dynamics CRM 2015 Online is Scheduling Product Upgrades to Update 1
A week ago I was getting frustrated because I love the new features that are coming down the pipe in Update 1 and my sandbox orgs are already upgraded, but I couldn't schedule my Update 1 for my production org.
Yesterday I finally was able to get it scheduled. The dates are already pushed out into July so you might want to get on that though!
-Happy Wednesday!
Yesterday I finally was able to get it scheduled. The dates are already pushed out into July so you might want to get on that though!
-Happy Wednesday!
Thursday, May 14, 2015
Annual Dynamics Product Satisfaction Survey is Here!
It's your chance to tell Microsoft what you think of their products!!
- Happy Thursday!
http://blogs.msdn.com/b/crm/archive/2015/05/13/calling-all-crm-online-customers-the-annual-dynamics-product-satisfaction-survey-is-here.aspx
- Happy Thursday!
Saturday, February 16, 2013
If You Have Trouble Connecting up to CRM Online (O365) Using the Outlook Client
I don't know why but it seems like lately using the old "CRM Online" in the server URL doesn't work anymore. I seem to have to use "https://disco.crm.dynamics.com" now.
I know Chris Cognetta from Tribridge has also blogged this, I haven't seen the article, but I am not the only one that this has caught off guard.
-Happy Saturday!
I know Chris Cognetta from Tribridge has also blogged this, I haven't seen the article, but I am not the only one that this has caught off guard.
-Happy Saturday!
Labels:
CRM,
CRM For Outlook,
CRM Online,
Microsoft CRM,
Microsoft Dynamics CRM
Friday, August 10, 2012
A New Blog You Might be Interested in If You Use Dynamics CRM Online
If you have Dynamics CRM Online or are an implementer of Dynamics CRM Online you might want to follow this new blog that has just been started by the product team.
I just wanted to drop a quick note that the Dynamics CRM Online Blog is now live: https://community.dynamics.
Have a great day!
Wednesday, September 28, 2011
Federated Active Directory Security Coming to Microsoft Dynamics CRM Online in Q4 2011
UPDATED! See Below.
I have seen questions in the forums and blogs before regarding the possibility of federated active directory security coming to Microsoft Dynamics CRM Online for some time now, but it sounds now like Microsoft has committed to a date. I first caught wind when I read this post (http://community.dynamics.com/product/crm/f/117/p/54548/98341.aspx), but figured it would still be awhile before it happened.
Then about a week ago, at the very first CRMUG meeting for the new Minnesota regional chapter, a Microsoft Employee that works specifically with CRM came out and said that it would be coming this year yet in Q4 along with a bunch of other feature enhancements that are going to be part of a first round of enhancements that is going to become a regular cycle as Microsoft is trying to move away from the big upgrades every 2 years or so in lieu of having more incremental enhancements on a more regular basis (maybe a couple times a year).
How about that! I am excited! Look out SalesForce. :)
Update! - I guess now it sounds like even though the linked "What's New!" document doesn't show it http://bit.ly/uHWumO It sounds like MSFT will be offering this to clients on a one by one basis starting in November.
I have seen questions in the forums and blogs before regarding the possibility of federated active directory security coming to Microsoft Dynamics CRM Online for some time now, but it sounds now like Microsoft has committed to a date. I first caught wind when I read this post (http://community.dynamics.com/product/crm/f/117/p/54548/98341.aspx), but figured it would still be awhile before it happened.
Then about a week ago, at the very first CRMUG meeting for the new Minnesota regional chapter, a Microsoft Employee that works specifically with CRM came out and said that it would be coming this year yet in Q4 along with a bunch of other feature enhancements that are going to be part of a first round of enhancements that is going to become a regular cycle as Microsoft is trying to move away from the big upgrades every 2 years or so in lieu of having more incremental enhancements on a more regular basis (maybe a couple times a year).
How about that! I am excited! Look out SalesForce. :)
Update! - I guess now it sounds like even though the linked "What's New!" document doesn't show it http://bit.ly/uHWumO It sounds like MSFT will be offering this to clients on a one by one basis starting in November.
Labels:
CRM,
CRM 2011,
CRM Online,
Microsoft Dynamics CRM
Friday, June 3, 2011
Update Roll-up 1 Outlook Client is Incompatible with Update Roll-up 2 (at least as applied to Microsoft Dynamics CRM 2011 Online)
It appears that update roll-up 2 is not compatible with the update roll up 1 Outlook client for Microsoft Dynamics CRM 2011. The same day that Microsoft Released roll-up 2 there have been several people complained of strange errors. This is mainly seen where customers are using CRM Online at this time and it appears that installing roll-up 2 fixes the issue.
Update 1: as of 6/3/2011 Microsoft's suggested fix of upgrading to update rollup 2 to fix the problem is not working for some CRM Online clients.
Update 2 :as of 6/3/2011 Microsoft says it will have a fix out within 2 weeks.
- I hope this helps!
Update 1: as of 6/3/2011 Microsoft's suggested fix of upgrading to update rollup 2 to fix the problem is not working for some CRM Online clients.
Update 2 :as of 6/3/2011 Microsoft says it will have a fix out within 2 weeks.
- I hope this helps!
Wednesday, March 16, 2011
RetrieveMultiple Calls in Jscript in Microsoft Dynamics CRM 2011
RetrieveMultiple is probably the most common call you will have to format up in your Microsoft CRM career, It has been for me anyways. I wanted to give you a couple examples of how to do this in Jscript. The first one is taken partially derived from the SDK that contains a linkentity (join) and the second is a simpler call that is a basic call that has criteria (where clause) but no links (joins).
This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this post: http://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html
These examples were formatted up using the soaplogger solution included in the SDK in conjunction with the CRM 2011 SOAP Request Formatter. The project for the formatter is at http://crm2011soap.codeplex.com/
To learn the ins and outs of parsing the response in 2011 using the DOM parser review this post.
http://mileyja.blogspot.com/2011/03/microsoft-dynamics-crm-2011-parsing.html
You can call either of these examples using the following in the GUI form eventhandler interface:
SDK.SAMPLES.RetrieveMultipleRequest
Call #1: returns (alerts) the name of the roles for a user when a valid guid is provided. (you will have to replace the guid with a valid one from your system) To do this see the systemuserbase table in your org database
Call #2: returns (alerts) the name of an account when a valid guid is provided. (you will have to replace the guid with a valid one from your system) To do this see the accountbase table in your org database. One other thing is that if you queried by a different attribute besides id you could get more than one record which is usually the point of a retrievemultiple.
I hope this helps!!
This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this post: http://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html
These examples were formatted up using the soaplogger solution included in the SDK in conjunction with the CRM 2011 SOAP Request Formatter. The project for the formatter is at http://crm2011soap.codeplex.com/
To learn the ins and outs of parsing the response in 2011 using the DOM parser review this post.
http://mileyja.blogspot.com/2011/03/microsoft-dynamics-crm-2011-parsing.html
You can call either of these examples using the following in the GUI form eventhandler interface:
SDK.SAMPLES.RetrieveMultipleRequest
Call #1: returns (alerts) the name of the roles for a user when a valid guid is provided. (you will have to replace the guid with a valid one from your system) To do this see the systemuserbase table in your org database
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
//This will establish a more unique namespace for functions in this library. This will reduce the
// potential for functions to be overwritten due to a duplicate name when the library is loaded.
SDK.SAMPLES = {
_getServerUrl: function () {
///<summary>
/// Returns the URL for the SOAP endpoint using the context information available in the form
/// or HTML Web resource.
///</summary>
var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
var serverUrl = "";
if (typeof GetGlobalContext == "function") {
var context = GetGlobalContext();
serverUrl = context.getServerUrl();
}
else {
if (typeof Xrm.Page.context == "object") {
serverUrl = Xrm.Page.context.getServerUrl();
}
else
{ throw new Error("Unable to access the server URL"); }
}
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl + OrgServicePath;
},
RetrieveMultipleRequest: function () {
var requestMain = ""
requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
requestMain += " <s:Body>";
requestMain += " <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
requestMain += " <request i:type=\"a:RetrieveMultipleRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
requestMain += " <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
requestMain += " <a:KeyValuePairOfstringanyType>";
requestMain += " <b:key>Query</b:key>";
requestMain += " <b:value i:type=\"a:QueryExpression\">";
requestMain += " <a:ColumnSet>";
requestMain += " <a:AllColumns>false</a:AllColumns>";
requestMain += " <a:Columns xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
requestMain += " <c:string>name</c:string>";
requestMain += " </a:Columns>";
requestMain += " </a:ColumnSet>";
requestMain += " <a:Criteria>";
requestMain += " <a:Conditions />";
requestMain += " <a:FilterOperator>And</a:FilterOperator>";
requestMain += " <a:Filters />";
requestMain += " </a:Criteria>";
requestMain += " <a:Distinct>false</a:Distinct>";
requestMain += " <a:EntityName>role</a:EntityName>";
requestMain += " <a:LinkEntities>";
requestMain += " <a:LinkEntity>";
requestMain += " <a:Columns>";
requestMain += " <a:AllColumns>false</a:AllColumns>";
requestMain += " <a:Columns xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
requestMain += " </a:Columns>";
requestMain += " <a:EntityAlias i:nil=\"true\" />";
requestMain += " <a:JoinOperator>Inner</a:JoinOperator>";
requestMain += " <a:LinkCriteria>";
requestMain += " <a:Conditions>";
requestMain += " <a:ConditionExpression>";
requestMain += " <a:AttributeName>systemuserid</a:AttributeName>";
requestMain += " <a:Operator>Equal</a:Operator>";
requestMain += " <a:Values xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
requestMain += " <c:anyType i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">81ED14D9-4441-E011-963A-080027AD5B6E</c:anyType>";
requestMain += " </a:Values>";
requestMain += " </a:ConditionExpression>";
requestMain += " </a:Conditions>";
requestMain += " <a:FilterOperator>And</a:FilterOperator>";
requestMain += " <a:Filters />";
requestMain += " </a:LinkCriteria>";
requestMain += " <a:LinkEntities />";
requestMain += " <a:LinkFromAttributeName>roleid</a:LinkFromAttributeName>";
requestMain += " <a:LinkFromEntityName>role</a:LinkFromEntityName>";
requestMain += " <a:LinkToAttributeName>roleid</a:LinkToAttributeName>";
requestMain += " <a:LinkToEntityName>systemuserroles</a:LinkToEntityName>";
requestMain += " </a:LinkEntity>";
requestMain += " </a:LinkEntities>";
requestMain += " <a:Orders />";
requestMain += " <a:PageInfo>";
requestMain += " <a:Count>0</a:Count>";
requestMain += " <a:PageNumber>0</a:PageNumber>";
requestMain += " <a:PagingCookie i:nil=\"true\" />";
requestMain += " <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>";
requestMain += " </a:PageInfo>";
requestMain += " <a:NoLock>false</a:NoLock>";
requestMain += " </b:value>";
requestMain += " </a:KeyValuePairOfstringanyType>";
requestMain += " </a:Parameters>";
requestMain += " <a:RequestId i:nil=\"true\" />";
requestMain += " <a:RequestName>RetrieveMultiple</a:RequestName>";
requestMain += " </request>";
requestMain += " </Execute>";
requestMain += " </s:Body>";
requestMain += "</s:Envelope>";
var req = new XMLHttpRequest();
req.open("POST", SDK.SAMPLES._getServerUrl(), true)
// Responses will return XML. It isn't possible to return JSON.
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
var successCallback = null;
var errorCallback = null;
req.onreadystatechange = function () { SDK.SAMPLES.RetrieveMultipleResponse(req, successCallback, errorCallback); };
req.send(requestMain);
},
RetrieveMultipleResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Recieves the assign response
///</summary>
///<param name="req" Type="XMLHttpRequest">
/// The XMLHttpRequest response
///</param>
///<param name="successCallback" Type="Function">
/// The function to perform when an successfult response is returned.
/// For this message no data is returned so a success callback is not really necessary.
///</param>
///<param name="errorCallback" Type="Function">
/// The function to perform when an error is returned.
/// This function accepts a JScript error returned by the _getError function
///</param>
if (req.readyState == 4) {
if (req.status == 200) {
//if (successCallback != null)
//***********************
// ALERT RESULT HERE
//***********************
alert(req.responseXML.xml.toString()); }
//}
else {
errorCallback(SDK.SAMPLES._getError(req.responseXML));
}
}
},
_getError: function (faultXml) {
///<summary>
/// Parses the WCF fault returned in the event of an error.
///</summary>
///<param name="faultXml" Type="XML">
/// The responseXML property of the XMLHttpRequest response.
///</param>
var errorMessage = "Unknown Error (Unable to parse the fault)";
if (typeof faultXml == "object") {
try {
var bodyNode = faultXml.firstChild.firstChild;
//Retrieve the fault node
for (var i = 0; i < bodyNode.childNodes.length; i++) {
var node = bodyNode.childNodes[i];
//NOTE: This comparison does not handle the case where the XML namespace changes
if ("s:Fault" == node.nodeName) {
for (var j = 0; j < node.childNodes.length; j++) {
var faultStringNode = node.childNodes[j];
if ("faultstring" == faultStringNode.nodeName) {
errorMessage = faultStringNode.text;
break;
}
}
break;
}
}
}
catch (e) { };
}
return new Error(errorMessage);
},
__namespace: true
};
Call #2: returns (alerts) the name of an account when a valid guid is provided. (you will have to replace the guid with a valid one from your system) To do this see the accountbase table in your org database. One other thing is that if you queried by a different attribute besides id you could get more than one record which is usually the point of a retrievemultiple.
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
//This will establish a more unique namespace for functions in this library. This will reduce the
// potential for functions to be overwritten due to a duplicate name when the library is loaded.
SDK.SAMPLES = {
_getServerUrl: function () {
///<summary>
/// Returns the URL for the SOAP endpoint using the context information available in the form
/// or HTML Web resource.
///</summary>
var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
var serverUrl = "";
if (typeof GetGlobalContext == "function") {
var context = GetGlobalContext();
serverUrl = context.getServerUrl();
}
else {
if (typeof Xrm.Page.context == "object") {
serverUrl = Xrm.Page.context.getServerUrl();
}
else
{ throw new Error("Unable to access the server URL"); }
}
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl + OrgServicePath;
},
RetrieveMultipleRequest: function () {
var requestMain = ""
requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
requestMain += " <s:Body>";
requestMain += " <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
requestMain += " <request i:type=\"a:RetrieveMultipleRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
requestMain += " <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
requestMain += " <a:KeyValuePairOfstringanyType>";
requestMain += " <b:key>Query</b:key>";
requestMain += " <b:value i:type=\"a:QueryExpression\">";
requestMain += " <a:ColumnSet>";
requestMain += " <a:AllColumns>false</a:AllColumns>";
requestMain += " <a:Columns xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
requestMain += " <c:string>name</c:string>";
requestMain += " </a:Columns>";
requestMain += " </a:ColumnSet>";
requestMain += " <a:Criteria>";
requestMain += " <a:Conditions>";
requestMain += " <a:ConditionExpression>";
requestMain += " <a:AttributeName>accountid</a:AttributeName>";
requestMain += " <a:Operator>Equal</a:Operator>";
requestMain += " <a:Values xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
requestMain += " <c:anyType i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">ABA9D2CE-CD4B-E011-9078-080027AD5B6E</c:anyType>";
requestMain += " </a:Values>";
requestMain += " </a:ConditionExpression>";
requestMain += " </a:Conditions>";
requestMain += " <a:FilterOperator>And</a:FilterOperator>";
requestMain += " <a:Filters />";
requestMain += " </a:Criteria>";
requestMain += " <a:Distinct>false</a:Distinct>";
requestMain += " <a:EntityName>account</a:EntityName>";
requestMain += " <a:LinkEntities />";
requestMain += " <a:Orders />";
requestMain += " <a:PageInfo>";
requestMain += " <a:Count>0</a:Count>";
requestMain += " <a:PageNumber>0</a:PageNumber>";
requestMain += " <a:PagingCookie i:nil=\"true\" />";
requestMain += " <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>";
requestMain += " </a:PageInfo>";
requestMain += " <a:NoLock>false</a:NoLock>";
requestMain += " </b:value>";
requestMain += " </a:KeyValuePairOfstringanyType>";
requestMain += " </a:Parameters>";
requestMain += " <a:RequestId i:nil=\"true\" />";
requestMain += " <a:RequestName>RetrieveMultiple</a:RequestName>";
requestMain += " </request>";
requestMain += " </Execute>";
requestMain += " </s:Body>";
requestMain += "</s:Envelope>";
var req = new XMLHttpRequest();
req.open("POST", SDK.SAMPLES._getServerUrl(), true)
// Responses will return XML. It isn't possible to return JSON.
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
var successCallback = null;
var errorCallback = null;
req.onreadystatechange = function () { SDK.SAMPLES.RetrieveMultipleResponse(req, successCallback, errorCallback); };
req.send(requestMain);
},
RetrieveMultipleResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Recieves the assign response
///</summary>
///<param name="req" Type="XMLHttpRequest">
/// The XMLHttpRequest response
///</param>
///<param name="successCallback" Type="Function">
/// The function to perform when an successfult response is returned.
/// For this message no data is returned so a success callback is not really necessary.
///</param>
///<param name="errorCallback" Type="Function">
/// The function to perform when an error is returned.
/// This function accepts a JScript error returned by the _getError function
///</param>
if (req.readyState == 4) {
if (req.status == 200) {
//if (successCallback != null)
alert(req.responseXML.xml.toString()); }
//}
else {
errorCallback(SDK.SAMPLES._getError(req.responseXML));
}
}
},
_getError: function (faultXml) {
///<summary>
/// Parses the WCF fault returned in the event of an error.
///</summary>
///<param name="faultXml" Type="XML">
/// The responseXML property of the XMLHttpRequest response.
///</param>
var errorMessage = "Unknown Error (Unable to parse the fault)";
if (typeof faultXml == "object") {
try {
var bodyNode = faultXml.firstChild.firstChild;
//Retrieve the fault node
for (var i = 0; i < bodyNode.childNodes.length; i++) {
var node = bodyNode.childNodes[i];
//NOTE: This comparison does not handle the case where the XML namespace changes
if ("s:Fault" == node.nodeName) {
for (var j = 0; j < node.childNodes.length; j++) {
var faultStringNode = node.childNodes[j];
if ("faultstring" == faultStringNode.nodeName) {
errorMessage = faultStringNode.text;
break;
}
}
break;
}
}
}
catch (e) { };
}
return new Error(errorMessage);
},
__namespace: true
};
I hope this helps!!
Labels:
CRM 2011,
CRM Online,
jscript,
Microsoft Dynamics CRM
Friday, March 11, 2011
Formatting Currency in Microsoft Dynamics CRM 2011 or 4.0 in Jscript
Hello everyone, I recently had a really hard time trying to find a good currency formatting function for Jscript that worked with CRM 2011 Jscript standards. I found a few functions that I could use together to do it, I have now just rolled them up into one for you guys.
I hope this helps, and Happy Friday!!!
//Format currency in CRM jscript
//EXAMPLE USAGE
//alert(FormatAsCurrency(10000));
function FormatAsCurrency(amount) {
var i = parseFloat(amount);
if (isNaN(i)) { i = 0.00; }
var minus = '';
if (i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if (s.indexOf('.') < 0) { s += '.00'; }
if (s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
amount = s;
var delimiter = ","; // replace comma if other mark is desired
var a = amount.split('.', 2)
var d = a[1];
var i = parseInt(a[0]);
if (isNaN(i)) { return ''; }
var minus = '';
if (i < 0) { minus = '-'; }
i = Math.abs(i);
var n = new String(i);
var a = [];
while (n.length > 3) {
var nn = n.substr(n.length - 3);
a.unshift(nn);
n = n.substr(0, n.length - 3);
}
if (n.length > 0) { a.unshift(n); }
n = a.join(delimiter);
if (d.length < 1) { amount = n; }
else { amount = n + '.' + d; }
amount = minus + amount;
return "$" + amount;
}
I hope this helps, and Happy Friday!!!
Labels:
CRM,
CRM 2011,
CRM Online,
Microsoft Dynamics CRM. jscript
Wednesday, December 1, 2010
Map Custom Attributes from Opportunity Product to Quote Product to Order Product and so on in Microsoft Dynamics CRM Online 2011 and 4.0
The process of mapping custom attributes in Microsoft Dynamics CRM Online from opportunity product to quote product to order product to invoice product is very similiar in CRM Online as it is in on-premise CRM. There is just one problem that needs to be overcome, and that is getting the GUID for the entitymap entities from the CRM backend to plug into the URL that is required to add custom attributes to the mappings.
If you want to know how this works in on-premise using SQL management studio please review my older blogpost at: http://mileyja.blogspot.com/2008_09_01_archive.html.
There are some issues that arise out of using CRM Online as you cannot access the SQL Server your instance resides on, this means you cannot easily get the GUIDs you need from the backend unless you use web services to retrieve them. I know the metadata browser in 4.0 does not show the entitymap entity in the menu as entity you can drill down on, but believe me you can access this entity using a retrieve or retrievemultiple call using SOAP in jscript through the 2007 web services (which were also conveniently left in place for backward compatibility in CRM 2011). The other issue is that there is a minor change to the URL you need to use to access the custom mapping as CRM Online follows the IFD url structure for where the orgname is located.
1. First, you will need this jscript that you can attach to any entity form event in CRM to get the guid when that event is executed in order to retrieve the unique entitymapid for your organization to map from salesorderdetail (Order Product) to invoicedetail (Invoice Product). Since this only needs to be done once, you can just attach it to an event and use the preview form function to retrieve the GUIDs and then remove the jscript without ever publishing it.
First in 4.0 Online or On-Premise:
//create SOAP envelope
var xmlSoapHeader= "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
var xmlAuthHeader = GenerateAuthenticationHeader();
var xmlSoapBody = "<soap:Body>" +
"<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"> " +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryByAttribute\" xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <q1:EntityName>entitymap</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>entitymapid</q1:Attribute>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" <q1:Attribute>targetentityname</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Attributes>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" </q1:Attributes>" +
" <q1:Values>"+
" <q1:Value xsi:type=\"xsd:string\">salesorderdetail</q1:Value>" +
" </q1:Values>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlt = xmlSoapHeader + xmlAuthHeader + xmlSoapBody;
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xmlt.length);
xmlHttpRequest.send(xmlt);
var resultXml = xmlHttpRequest.responseXML.xml;
alert(resultXml);
Now in CRM 2011 Online or On-Premise you can use the same script, but it must be encapsulated in a jscript library as a function that you call from the event:
function testfunc()
{
//create SOAP envelope
var xmlSoapHeader= "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
var xmlAuthHeader = GenerateAuthenticationHeader();
var xmlSoapBody = "<soap:Body>" +
"<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"> " +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryByAttribute\" xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <q1:EntityName>entitymap</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>entitymapid</q1:Attribute>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" <q1:Attribute>targetentityname</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Attributes>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" </q1:Attributes>" +
" <q1:Values>"+
" <q1:Value xsi:type=\"xsd:string\">salesorderdetail</q1:Value>" +
" </q1:Values>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlt = xmlSoapHeader + xmlAuthHeader + xmlSoapBody;
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xmlt.length);
xmlHttpRequest.send(xmlt);
var resultXml = xmlHttpRequest.responseXML.xml;
alert(resultXml);
}
2. Now run the form event you attached the jscript to.
The alert message is a little bit difficult to look at when the script executes, but if you use fiddler to capture your sessions, it will show you the needed entitymapid GUID quite nicely:
3. Now you can piece together the URL for the mapping interface for the custom attribute mapping. The syntax to use is:
https://myorgsubdomain.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=entitymapidGUID
Here is a syntax example using the guid above:
https://myspecialcrminstance.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=EB562CC6-991B-DF11-87A9-02BF0A0679DE
NOTE: Since the GUIDs are unique to each organization of CRM, the GUID in the URL won't actually work except in my own personal organization.
4. Navigate to the URL using your browser and below is the resulting screen. You should see a similiar mapping dialog when you click "New" on the screen. I chose to show you the end result from 2011 in the following screenshot for the mapping screen, it looks only a bit different in 4.0 Online and functions the same way.
Thats all there is to it, just add you mappings as needed. If you need to get the other GUIDs for the other detail (product) entities in the sales process chain you just change the entity types in the script and re-run it.
This post is provided as-is and implies no warranty, Jamie Miley does not assume any responsibility for problems arising from the use of this information.
If you want to know how this works in on-premise using SQL management studio please review my older blogpost at: http://mileyja.blogspot.com/2008_09_01_archive.html.
There are some issues that arise out of using CRM Online as you cannot access the SQL Server your instance resides on, this means you cannot easily get the GUIDs you need from the backend unless you use web services to retrieve them. I know the metadata browser in 4.0 does not show the entitymap entity in the menu as entity you can drill down on, but believe me you can access this entity using a retrieve or retrievemultiple call using SOAP in jscript through the 2007 web services (which were also conveniently left in place for backward compatibility in CRM 2011). The other issue is that there is a minor change to the URL you need to use to access the custom mapping as CRM Online follows the IFD url structure for where the orgname is located.
1. First, you will need this jscript that you can attach to any entity form event in CRM to get the guid when that event is executed in order to retrieve the unique entitymapid for your organization to map from salesorderdetail (Order Product) to invoicedetail (Invoice Product). Since this only needs to be done once, you can just attach it to an event and use the preview form function to retrieve the GUIDs and then remove the jscript without ever publishing it.
First in 4.0 Online or On-Premise:
//create SOAP envelope
var xmlSoapHeader= "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
var xmlAuthHeader = GenerateAuthenticationHeader();
var xmlSoapBody = "<soap:Body>" +
"<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"> " +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryByAttribute\" xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <q1:EntityName>entitymap</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>entitymapid</q1:Attribute>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" <q1:Attribute>targetentityname</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Attributes>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" </q1:Attributes>" +
" <q1:Values>"+
" <q1:Value xsi:type=\"xsd:string\">salesorderdetail</q1:Value>" +
" </q1:Values>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlt = xmlSoapHeader + xmlAuthHeader + xmlSoapBody;
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xmlt.length);
xmlHttpRequest.send(xmlt);
var resultXml = xmlHttpRequest.responseXML.xml;
alert(resultXml);
Now in CRM 2011 Online or On-Premise you can use the same script, but it must be encapsulated in a jscript library as a function that you call from the event:
function testfunc()
{
//create SOAP envelope
var xmlSoapHeader= "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
var xmlAuthHeader = GenerateAuthenticationHeader();
var xmlSoapBody = "<soap:Body>" +
"<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\"> " +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryByAttribute\" xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <q1:EntityName>entitymap</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>entitymapid</q1:Attribute>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" <q1:Attribute>targetentityname</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Attributes>" +
" <q1:Attribute>sourceentityname</q1:Attribute>" +
" </q1:Attributes>" +
" <q1:Values>"+
" <q1:Value xsi:type=\"xsd:string\">salesorderdetail</q1:Value>" +
" </q1:Values>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlt = xmlSoapHeader + xmlAuthHeader + xmlSoapBody;
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xmlt.length);
xmlHttpRequest.send(xmlt);
var resultXml = xmlHttpRequest.responseXML.xml;
alert(resultXml);
}
2. Now run the form event you attached the jscript to.
The alert message is a little bit difficult to look at when the script executes, but if you use fiddler to capture your sessions, it will show you the needed entitymapid GUID quite nicely:
3. Now you can piece together the URL for the mapping interface for the custom attribute mapping. The syntax to use is:
https://myorgsubdomain.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=entitymapidGUID
Here is a syntax example using the guid above:
https://myspecialcrminstance.crm.dynamics.com/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=EB562CC6-991B-DF11-87A9-02BF0A0679DE
NOTE: Since the GUIDs are unique to each organization of CRM, the GUID in the URL won't actually work except in my own personal organization.
4. Navigate to the URL using your browser and below is the resulting screen. You should see a similiar mapping dialog when you click "New" on the screen. I chose to show you the end result from 2011 in the following screenshot for the mapping screen, it looks only a bit different in 4.0 Online and functions the same way.
Thats all there is to it, just add you mappings as needed. If you need to get the other GUIDs for the other detail (product) entities in the sales process chain you just change the entity types in the script and re-run it.
This post is provided as-is and implies no warranty, Jamie Miley does not assume any responsibility for problems arising from the use of this information.
Labels:
2011,
4.0,
CRM,
CRM Online,
Microsoft Dynamics CRM,
Online
Subscribe to:
Posts (Atom)

