Friday, March 26, 2010

Populate CRM Fields from Parent Window

There are a number of people who have posted about copying a record via JScript button in CRM, and this post isn't far off from that concept. My coworker found a great way to implement the concept of opening a record and populating fields on the newly opened window, based on data from the originating window. And that is quickly opening an activity.

This customization cuts down the number of clicks to open a new Activity from 4, down to 1. 4 being click on the record you wish to create an activity for, click "Activities", click "New", click the activity type, click Ok. You can double click on the activity type to open it, but that's still 4 clicks technically. With this customization, users just click the button of the activity type. Done.

In a piece of software where users already feel like there are a lot of clicks and windows, this helps significantly.

Ok, now the good part. How do we do it?

Add a button to the entity you want to apply this customization to within the ISV.config file (in this example I use the contact):

<Entity name="contact" >
<ToolBar ValidForCreate="0" ValidForUpdate="1">
<Button Icon="/_imgs/ico_16_142.gif"
JavaScript="window.open('http://crmserver/CompanyName/activities/appointment/edit.aspx?');" PassParams="1"
WinParams="" WinMode="0">
<Titles>
<Title LCID="1033" Text="New Activity" />
</Titles>
<ToolTips>
<ToolTip LCID="1033" Text="Create new appointment activity" />
</ToolTips>
</Button>
</ToolBar>
</Entity>

Now, on the OnLoad script of the given activity (in this case the Appointment), add the following code:

//appointment onload script
if (window.opener.crmForm) {
var rgid = window.opener.crmForm.ObjectId;
var rgtype = window.opener.crmForm.ObjectTypeCode;
}
if (rgtype == 1) {
var rgname = window.opener.crmForm.all.name.DataValue;
}
if (rgtype == 2) {
var rgname = window.opener.crmForm.all.fullname.DataValue;
}

if (rgid != null) {
var oItems = new Array();
oItems[0] = new LookupControlItem(rgid, rgtype, rgname);

crmForm.all.regardingobjectid.DataValue = oItems;
}


Done. Not too difficult and end users will love it.

David Fronk
Dynamic Methods Inc.

Friday, March 05, 2010

Integrations: In-line versus Queue/Batch Based

I love web services. They make it so that one system can send and receive data from some completely different system from anywhere over the web. Data gets updated, end users can see the latest and greatest data essentially instantaneously. With CRM plugins you can have in-line integrations that just push data from CRM to whatever system you want on a save, reassignment, deletion, etc. Or, you could pull data from another system whenever a page loaded, all through plugins. That's awesome.

Queue, or batch, integrations take note of everything that changes and then runs a process at a given time interval and pushes all of the data that has been queued up into the other system. Web services can be used to push/pull data in this data from the queue in batch fashion and keep systems in sync. But typically when these batches are run they put a load on the server and could be rather resource intensive. And data isn't updated instaneously, it gets updated shortly after the predetermined time interval. If this is nightly that might be too stale for some people. Depending on the data though, that may be more than sufficient.

However, when those web services don't work (when either server goes down, gets overloaded, etc) it's REALLY bad. Things either get out of sync, or else your integration just got a whole new level of complexity; waiting, or holding the data, until the other system comes back online. In the debate of in-line versus queue based integrations, queue based gets a point here. If the server is down, the queue based system gracefully errors, noting that the remote server is down, and the next time it runs it picks up where it left off and tries again. In-line dies and doesn't get the data transimitted across. The best it can do is error and put its data into a record to get queued up and processed at a later time...via a queue based integration.

I have recently worked with a system that went down at least twice a day. Originally it was thought that an in-line integration would work just fine. But since the receiving server has been down I now have to include or move to a queue based integration in case the in-line goes down.

Each has their use, and I want the in-line to work because in my mind it's the best. But in reality, the queue based, though "slower", is the most reliable.

If any one has any thoughts or input, we'd love to hear it.

David Fronk
Dynamic Methods Inc.