Friday 25 January 2008

Meeting room booking in MS CRM?

I have been moved to comment on this because I chanced across a couple of whitepaper downloads from Microsoft recently on the subject of Service Scheduling. It is suggested that even large scale companies can consider using MS CRM for their room booking requirements. You can find the performance testing results here. Please look at the type of high-performance hardware they deduce is necessary to meet their 'acceptable' response rates.

It took me back to a project we undertook for a global corporate at the beginning of the century(!). This large company was attempting to use Outlook / Exchange functionality for booking their 80+ meeting rooms. Finding problems, they first banned users from trying to book their own rooms because the network and servers began to get over-stressed with the loading, when in fact being a telecoms company their network bandwidth was enormous! Pretty soon this issue escalated to mission-critical when Exchange servers started dying all around.

So what we did was to decouple the two areas - we developed a web-based employee self-service application which is hosted within their portal, which is not that complex, and uses availability snapshots to present the user with booking choices. The user submits a request and if the resource is still available you get immediate confirmation. The design of the database and stored procedures means double-bookings are impossible.

But now of course there is the ever-present pressure to amalgamate applications with Total Cost of Ownership (TCO) arguments and the emergence of SOA. So what we have done is simply to make our room booking system accessible 'through' the MS CRM sitemap. Take a look at the first draft of a solution we can provide. And remember, you will not risk your CRM system becoming sluggish and unresponsive, but you will have an optimised solution for your business issue, which is accessible from anywhere and you won't have to buy user licenses just for users to access room booking.

If there is demand I can see a case for configuring the system using MS CRM entities, but I strongly believe that the 'booking engine' should remain optimised for its specific purpose. I'm looking to test the demand for a powerful quite inexpensive solution accessible through the add-in route, and would appreciate comments.

Monday 21 January 2008

Email Source Edit Function

If you've ever used email quick campaigns or email activities in normal campaigns you've likely been frustrated at the spontaneously re-formatting that sometimes happens when you paste in some content from your favourite HTML editor program. Oh, why doesn't the editor have a 'View Source' button to see what's actually there? Well, this post shares with you how you can add such a feature in an unsupported but minimally invasive way.

First of all the concept. We know the page is generated in code and we're not about to hack into this territory! Fortunately though, it's quite easy to hook into the onload event and run some javascript to add a button which will do what we want. After this we need to use the (toggle) button to replace the standard WSIWUG editor iFrame with a textarea for the source view and a few lines of code to shift your content between the different elements. Really the only thing we have to ensure is that when editing in source mode we ensure the body tag is contentEditable to be able to edit again in WSIWYG!

Note: I have found that an invaluable tool in any exploit of this kind is the IE DOM Explorer (downloadable from Microsoft), which allows you to easily locate elements and test dynamic manipulation of the document object. Although if you're trying to get to pages displayed in dialogs you have to be a little inventive ;-)

Step 1: So to begin with we'll add a script to the page of interest (say emailForm.aspx) and attach an event handler to run this button with document.body.onload. You can see that basically we're going to replace the first toolbar button with a longer piece of HTML which also includes the new button and a spacer. An alternative and more elegant way would be to clone(deep) the element, setting the desired properties and then inserting the new element in the DOM.

//this is the spacer
sp = "<td unselectable="'on'">";
sp += " <div unselectable="'on'"></div></td>";

function addViewSourceBtn(){
var t = document.getElementById("HTMLBAR");//get the toolbar
var c = t.getElementsByTagName("TD")[0].outerHTML; //get the first btn
var v = c.replace("cmd-cut.gif","cmd-insertKB.gif"); //clone and change
v = v.replace("Cut","Source");
v = v.replace("HTMLBAR.htmlExec('cut')","ViewSource()");
t.outerHTML = t.outerHTML.replace(c,v+sp+c); //recreate the toolbar
}

Step 2: Anyway, the major part of the task is in the function which is called by the button.

  1. First of all we're going to initialise a variable to hold the current [mode] of the button in the script. Alternatively, we could have stored this as an expando on the button and changed its appearance perhaps. We also have a variable [RichEdit] which holds the initial iFrame HTML outerHTML, but we could easily hardcode it as per [TextEdit].
  2. When we switch to source edit mode, we're going to disable any wizard buttons (say in the quick campaign wizard) and hide all the other toolbar buttons.
  3. So then when we toggle to source edit we set the value of the textbox, and the other way we need to write the document for the iFrame.

That's it! Enjoy.

UPDATE: Of course the better way to do this is use this code in the customisable email onload handler in MSCRM. This saves you having to make any edits to the pages themselves which is strictly unsupported.

function ViewSource(){
// define different editors
var TextEdit = '<textarea ID="descriptionIFrame" style="width:100%;height:100%;"></textarea>';
var editor_obj = document.all['descriptionIFrame'];

if (mode == "textedit") {
mode = 'wysiwyg';
with(window.parent){
document.all['btn_id_Next'].disabled=true;
document.all['btn_id_Back'].disabled=true;
}
var editdoc = editor_obj.contentWindow.document;
var contents = editdoc.documentElement.outerHTML;
editor_obj.outerHTML = TextEdit;
var editor_obj = document.all['descriptionIFrame'];
editor_obj.value = contents;

b = document.all['HTMLBAR'].getElementsByTagName("TD");//hide wysiwyg buttons
for (i=0;i<b.length;i++){with(b[i]){ if (title!='Source')style.visibility='hidden'; } }

} else {
mode = 'textedit';
var contents = editor_obj.value;
editor_obj.outerHTML = RichEdit;
var editor_obj = document.all['descriptionIFrame'];
var editdoc = editor_obj.contentWindow.document;

editdoc.open();
editdoc.write(contents);
editdoc.close();

b = document.all['HTMLBAR'].getElementsByTagName("TD");//show wysiwyg buttons
for (i=0;i<b.length;i++){b[i].style.visibility='';}

with(window.parent){
document.all['btn_id_Next'].disabled=false;
document.all['btn_id_Back'].disabled=false;
}
}
}

Accessing Manual Workflow for Activities

I have noticed that many people want to run manual workflow rules against activities, such as marking a whole lot of email activities as COMPLETED, but have been frustrated that there is no ApplyRule option on the activities grid toolbar, meaning you have to drill into each one to get the menu option.

Does anyone know why? Anyway, I decided to add a button right back there and try it - well it appears to work! Simply use the following function on loading the home_activities.aspx page.

<script>
function addApplyRuleBtn(){
//var t = document.getElementById("mnuBar1");//get the toolbar
d = document.getElementById("_MBdoActioncrmGrid4200delete");
ar = d.cloneNode(true);
ar.id = "_MBdoActioncrmGrid4200applyrule";
ar.title = "Apply Rule";
ar.action = "doAction('crmGrid', '4200', 'applyrule')";
ar.firstChild.firstChild.src="/_imgs/ico_18_4212.gif";
d.parentElement.appendChild(ar);
}
</script>


Of course this is unsupported, but really quite minimally invasive.

Vizola eMarketing Add-in

This is an un-ashamed plug for something developed to meet our own needs, but from reading newsgroups' posts seems to have more general interest...
In short, when we implemented our CRM system we had specific expectations on some things we'd like to do, and unfortunately these were not catered for out-of-the-box - things like being able to send out email newsletters and monitor interest.
We wanted to know what events, products, services etc. were most of interest and capture that directly in the CRM. We wanted to know how many people were reading the emails or whether they were being bounced for whatever reason. And we wanted to have better control over the content presentation.
For these and several other reasons (see here) I set about learning about MS CRM and adding functionality at the same time, and still it goes on... And naturally, using the functions always promotes further ideas for inclusion.
Meanwhile the focus behind creating this add-in was always to solve a business issue, and with this in mind I'm providing source code for organisations to further customise or enhance for their own purposes (re-selling excluded ;-), and not spending time on trying to 'shrink-wrap' and license per user. I have posted some more information here, but by all means contact me for further details, and watch this space...