Tuesday, 28 April 2015

CRM 2015 - Javascript - {Personal Opinion #1 - Considerations on customizing CRM Forms}

 Extending a lookup control for people that have been working with CRM sometimes looks like a nightmare, and why? 


The reason for this is related with upgrades, I remember for instance that form CRM 3.0 to CRM 4.0, the way our development team was using this functionality on upgrading it would break the custom filtering.


Honestly, i'm not the kind of guy that likes to extend to much the CRM in terms of Javascript because of many reasons, i'm not saying i don't customize, but i think in very single detail, what are the consequences of doing everything, before doing it.


Usually everything gets clear to me when i think on the word "Upgrade", if i think:

Ok, i can do this in 2 hours instead of spending 8 hours, however, in the future i will be in trouble because it can break, i prefer to be honest to the customer and say what i think is the best in here.


Sometimes, the last sentence in CRM is more clear for people with years of experience in the product, because we got already so many hours trying to fix things that were Out of The Box that from one minute to the other with no reason just stop to work. 


In here i will spend few more hours because it is my work that's on the spotlight.


Now everything is much better in terms of the framework provided from Microsoft to customize the forms, it is possible using that framework to control almost every type of control (field, web  resource, grid,..) that is indeed a big help for us developers.


I will leave in here the word Encapsulation, in few words is: "Packing of data and functions into a single component.", and why? Because if instead of doing methods without thinking of reusing them, is already as headache, if something breaks and you have to fix in every single location you are using that piece of code, so, every time i need to do something i think, am i seeing to use this in more than one place? If yes, ok, lets create a function in a common file. 

With this approach, if something needs to be changed in that functionality, you need only to change in one place. 


Hope it helps.

Tuesday, 21 April 2015

CRM 2015 Online 2015 Update 1 - Optimistic Concurrency

 How many times were you been asked by a customer the following?

If 2 users open the same record, what will happen in terms of database.


The answer would be simple. Last update wins. It means, the data that will be saved by last will win.


Now, reading MSDN, i can see that probably with the Update 1 to the Online we will be able to control that.

If we create a Pre-Plugin for the Update Message on the entities we will need to detect if someone or something updated the same record,from the moment we opened until the moment we are updating. 

The fields we can use for that are:
  • ConcurrencyVersionMismatch 
  • RowVersion

More information on this subject, please have a look on the MSDN page while i can't do myself some tests to understand better how this works.


Hope it helps.

Saturday, 18 April 2015

CRM 2015 - {Javascript Code Example #1} - Grid Objects and Methods

 When we need to extend the Grids trough Javascripts, we should use the client sdk to avoid problems in the future, not only because of upgrades, but as well update rollups.


Reading an article from MSDN, found written that only the refresh method was available, what means other extensions were not "supported". 


This few examples are can applied to a CRM 2015 Online Organization with Update 1. Hope that it can be available as well for OnPrem near in the future.


1. Getting the Grid Control, and it was already working previously:

var contactsSubgrid = Xrm.Page.getControl("Contacts");

2. Add an event on load:

var myContactsGridOnloadFunction = function () { console.log( "Contacts Subgrid OnLoad occurred" ) }; 

Xrm.Page.getControl( "Contacts" ).addOnLoad(myContactsGridOnloadFunction);

3. Get all rows:

var allRows = Xrm.Page.getControl( "Contacts" ).getGrid().getRows(); 

Source of the code:


I will do more examples with this, and write a new version of tested methods and results.

Hope it can help.

Thursday, 16 April 2015

CRM 2015 - Perform specialized operations using Update

Functionality now available on release of new sdk release (7.1.a ,March 2015)

Before this release, some specialized messages should be called to update some entity fields, methods like assign request or set state request.


However, from this release on it would be able to be done from the Update message. 


Please see the below table to see what are the deprecated methods.


Deprecated message request Attribute to update 

AssignRequest 

<entity>. OwnerId 

SetStateRequest 

<entity>. StateCode 

Important 
For   SLA   and   RoutingRule   entities, changing the   OwnerId   and   StateCode   in a single   Update   message invocation is not supported and results in an exception. 

SetParentSystemUserRequest 

SystemUser.ParentSystemUserId 

SetParentTeamRequest 

Team.BusinessUnitId 

SetParentBusinessUnitRequest 

BusinessUnit.ParentBusinessUnitId 

SetBusinessEquipmentRequest 

Equipment.BusinessUnitId 

SetBusinessSystemUserRequest 

SystemUser.BusinessUnitId 

*<entity> refers to any entity that provides this attribute. 

Source of the information:

https://msdn.microsoft.com/en-us/library/dn932124.aspx 


Hope in helps.

Wednesday, 15 April 2015

CRM 2015 - Microsoft.Xrm.Sdk - UpsertRequest Class

 New method available for the purpose of integration, at least is the reason Microsoft is saying for the availability of this class, and as well in the article says:

[This topic is pre-release documentation and is subject to change in future releases.] 

Warning

For Microsoft Dynamics CRM Online organizations, this feature is available only if your organization has updated to Dynamics CRM Online 2015 Update 1. This feature is not available for Dynamics CRM (on-premises). 


I see good value in here for integration purposes of course, instead of using a Retrieve to see if a record exists or not, and after using the CreateRequest or UpdateRequest methods according if the record exists or not, you will be able to use the UpsertRequest.


In terms of development it will decrease, and i would say that it is a big help, however as Microsoft says, please don't use this always, it has a cons of course, it is a heavier  operation, because inside it is doing the retrieve, and create or update after.


So, for now it will be available in Online and not On Premesis, lets have the fingers crossed for having as well in On Premesis.


Source is below:

https://msdn.microsoft.com/en-us/library/dn932135.asp

Tuesday, 14 April 2015

CRM 2015 - Microsoft.Xrm.Client DLL - Round DateTime To

 Having a look on my CRM Bible (SDK), i have found a Enumeration to Round Dates to: Day, Hour, Minute, Second and Month. So, i had to test that.

Always good to know this things, instead of doing extra lines of code or using other libraries for this, why not using default capabilities of CRM dlls.

DateTime dt = Microsoft.Xrm.Client.DateTimeExtensions.Round(DateTime.Now, Microsoft.Xrm.Client.RoundTo.Day);


Result will be:{15/04/2015 00:00:00}


Hope it helps.

Monday, 13 April 2015

CRM 2015 - Customizations - Change CSS

 Before staring to tell what was happening to me, i have to say I'm the first to say to avoid this kind of customizations, however and because of a need i had to do this.


I needed to add a border to the fields in a form even if they were not with the focus on them. So, the only way of doing that is applying some kind of CSS to them, i found some articles and i have chosen the below one.


 function load_css_file(filename) { 

 var fileref = document.createElement("link"); 

 fileref.setAttribute("rel", "stylesheet"); 

 fileref.setAttribute("type", "text/css"); 

 fileref.setAttribute("href", filename); 

 document.getElementsByTagName("head")[0].appendChild(fileref);

}


function customizeFormsCss() { //inject css file to the header load_css_file("WebResources/ttt_CRM.CSS.FormCustomization"); 

}

Now, it comes the funny part that made me waist a lot of time. A colleague just started to do the developments, and it was working in his laptop (IE and Chrome), however it was not working in mine. So, the next thing that i did was, lets import to a new organization, and in my laptop started to work.

So, after hours and because i deployed as well to a VM, into two different organizations, and it was working perfectly. 

After digging a little bit more, and because with this i taught that only could be something related to a configuration in the Organization, i discovered the reason. :)

In the one that it was not working, i have selected the below check box, after not selecting it started to work.

Hope to help more people with this.

Sunday, 12 April 2015

CRM 2015 - Javascript - Opening a Web Resource

 Javascript function from the Namespace Xrm.Utility that can be called to open a Web Resource with the possibility of adding parameters. Bare in mind that cannot that this function will not work with Microsoft Dynamics CRM for tablets.   

Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height) 

Parameters 

  

Name Type Required Description 

webResourceName 

String 

Yes 

The name of the HTML web resource to open. 

webResourceData 

String 

No 

Data to be passed into the data parameter. 

width 

Number 

No 

The width of the window to open in pixels. 

height 

Number 

No 

The height of the window to open in pixels. 

Return Value 

Window object. 

Remarks 

An HTML web resource can accept the parameter values described in   Passing Parameters to HTML Web Resources . This function only provides for passing in the optional data parameter. To pass values for the other valid parameters, you must append them to the webResourceName   parameter. 

Examples 

Open an HTML web resource named “new_webResource.htm” 

Xrm.Utility.openWebResource( "new_webResource.htm" ); 

Open an HTML web resource including a single item of data for the data parameter 

Xrm.Utility.openWebResource( "new_webResource.htm" , "dataItemValue" ); 

Open an HTML web resource passing multiple values through the data parameter 

 var  customParameters = encodeURIComponent( "first=First Value&second=Second Value&third=Third Value" );Xrm.Utility.openWebResource( "new_webResource.htm" ,customParameters); 

noteNote 
These values have to be extracted from the value of the data parameter in the HTML web resource. For more information, see   Sample: Pass multiple values to a web resource through the data parameter 

Open an HTML web resource with the parameters expected by HTML web resources 

Xrm.Utility.openWebResource( "new_webResource.htm?typename=account&userlcid=1033" ); 

For more information, see   Passing Parameters to HTML Web Resources 

Open an HTML web resource, setting the height and width 

Xrm.Utility.openWebResource( "new_webResource.htm" , null , 300,300); 


From MSDN: https://msdn.microsoft.com/en-us/library/jj602956.aspx#BKMK_OpenWebResource 

Hope it helps.

Friday, 10 April 2015

CRM 2015 - Javascript - Opening an Entity Form from Javascript

 Opening a form where you can say if it will open on the same window or another window it will be possible on the Microsoft Dynamics CRM Online 2015 Update 1.


In old times you would use the window.open, but my Microsoft and say as well as a best practice you should use the Xrm.Utility (client-side reference).


Now it will be possible to pass if you want to open on the same window or in a new window as you can see from the below information that i took from the MSDN.



Opens an entity form for a new or existing entity record using the options you set as parameters. 

Xrm.Utility.openEntityForm(name,id,parameters,windowOptions) 

Parameters 

  

Name Type Required Description 

name 

String 

Yes 

The logical name of the entity. 

id 

String 

No 

The string representation of a unique identifier or the record to open in the form. If not set, a form to create a new record is opened. 

parameters 

Object 

No 

A dictionary object that passes extra query string parameters to the form. Invalid query string parameters will cause an error. 

Valid extra query string parameters are: 

windowOptions 

Object 

No 

For Microsoft Dynamics CRM Online 2015 Update 1 or later use this optional parameter in the web application to control how the form opens. You can choose to open a form in a new window by passing a dictionary object with a boolean   openInNewWindow   property set to   true 

Remarks 

Using this function helps ensure that users are not prompted to log in again under certain circumstances. 

Examples 

Open a new account record using the default form 

Xrm.Utility.openEntityForm( "account" ); 

Open an existing account record using the default form 

Xrm.Utility.openEntityForm( "account" , "A85C0252-DF8B-E111-997C-00155D8A8410" ); 

Open a new account record with a specific form and setting default values 

 var  parameters = {};parameters[ "formid" ] = "b053a39a-041a-4356-acef-ddf00182762b" ;parameters[ "name" ] = "Test" ;parameters[ "telephone1" ] = "(425) 555-1234" ;Xrm.Utility.openEntityForm( "account" , null , parameters); 

Open a new account record using the default form in a new window 

 var  windowOptions = { openInNewWindow: true };Xrm.Utility.openEntityForm( "account" , null , null ,windowOptions); 

Hope it helps.

Wednesday, 8 April 2015

CRM 2015 - Javascript - Closing a CRM Form in Javascript

 I had the need of adding an additional button to a form "Submit and Close" for business process purposes.

In there doing some code, in the end only needed to call to do whatever i needed:

Xrm.Page.data.entity.save("saveandclose");

Xrm.Page.ui.close();

However, doing that, and because i was calling the for from a Web Resource, the form was being closed but the originating web resource was appearing, the solution is simple, change the last line by:

if (parent.opener != undefined) { window.parent.close(); } else Xrm.Page.ui.close();

In my perspective, it seems that CRM if has a parent.opener, just redirects to that location, even if we are calling the close of the window trough the Xrm.Page.Ui object.

Any thoughts, please let me know.

Hope is useful.

Friday, 3 April 2015

CRM 2015 - Using Lookups for Entity Records in Workflows(Processes) or in Views

This can apply for more, but at least is a common issue that we as crm developers, architects, have to deal with (on views and processes).

Few projects we need to use in Processes or in Views some Lookups for records that you cannot import (System Users, BU's,...) across multiple domains (Dev, UAT and Production for example).

I know, we always can create more entities for that purpose, however, it can be painful to manage after few deploys of new releases.

But, trying to import a Solution with views and processes with references to non existent records, it will bring: sometimes failure of the import or in processes, processes with references to non existent records it will become in Draft, and when i import a solution i expect to have all working.

In here, the easier solution that i have found was, having a file with "Old Guid", "New Guid" in each line, and with a Console Application with all variables configured trough the app.config or custom mappings file, Unzip the exported Solution, open all the files of the solution and replace in all the "Old Guid" by the "New Guid", zip again and Import to the new environment.

I can ensure that it will work, and i don't see honestly any problem of doing this.

Hope it helps.

CRM 365 Cloud - Disassociate 2 records using typescript

In case you need to Disassociate 2 records, please find below the code that allows you to do that.      export async function DissociateE...