Search This Blog

Thursday, December 13, 2018

If anyone reads this... go to readyxrm.blog

We are almost in 2019.  I am blogging fairly regularly at https://readyxrm.blog

Cheers
Nick

Wednesday, January 20, 2016

Oh, we aren't here anymore...

Its been over 2 years now that we have shut down ReadyBMS and the team has joined BDO Canada LLP.


For new blog postings (from us and other great BDO team members) regarding CRM, please go here:


http://www.bdosolutions.com/ca/insights/category/software/crm/


Thanks for all the support!
Nick

Thursday, March 20, 2014

Issue with Case Resolutions in CRM 2013 / CRM Online

There is an issue in CRM 2013/CRM Online when you resolve a case, the "resolution" description gets overwritten with "Resolve Case".  This worked in CRM 2011. 

In CRM 2011:
You resolve a case and enter in the mandatory Resolution Comment field:

Looking at the corresponding Case Resolution Activity, you see your description:



 
All good.  Now we try the same thing in CRM 2013:
 

And the corresponding Resolution has turned into "Resolve Case" !


Apparently this is a known issue and is addressed in CRM 2013 Rollup 2.  As of this post (March 21) Rollup 2 has not yet been released nor has it been rolled out to CRM Online.  Just thought I would mention it in case someone is banging their head against a wall trying to figure this out!

Cheers
Nick

 




Sending Meeting Invites from CRM Appointments

Quick and dirty post:

Here is some code that I wrote that will enable you to send meeting invites direct from an Appointment form.  Note that creating an appointment will not send a meeting request for the participants unless you first sync to Outlook and then send.  This will open up Outlook directly and allow you to hit the 'send invites' button.

This uses activex so for now its something that only works in IE.  This code is in raw form so take it for what it is and at your own risk!
:

if (typeof (ND) == "undefined")
{ND = { __namespace: true }; }
ND.ApptLib = { __namespace: true };
ND.ApptLib.OnSave = function ()
 
{

//if send meeting invite is true then create outlook meeting invite.
if (Xrm.Page.getAttribute("rxrm_sendmeetinginvites").getValue() == true)
 
{

try
{
//sets up Outlook Appointment type object
var objOL //As Outlook.Application;
var objAppt //As Outlook.AppointmentItem;
var olAppointmentItem = 1;
var olMeeting = 1;
 

var requiredattendeeemails = "";
var optionalattendeeemails = "";
//loops through list of attendees
 
 
 

if(Xrm.Page.getAttribute("requiredattendees").getValue() != null)
 
{

var RequiredAttendeesArr= new Array;
RequiredAttendeesArr = Xrm.Page.getAttribute("requiredattendees").getValue();
 

//checks to see what kind of entities as email schema names are different
for (i = 0; i <= RequiredAttendeesArr.length -1; i++)
 
{
switch(RequiredAttendeesArr[i].entityType)
{

case "equipment":
var cols = ["emailaddress"];
var atr = "emailaddress";
break;
case "systemuser":
var cols = ["internalemailaddress"];
var atr = "internalemailaddress";
break;
default:
var cols = ["emailaddress1"];
var atr = "emailaddress1";
break;
 
}

//start building email list
var retrievedparty = XrmServiceToolkit.Soap.Retrieve(RequiredAttendeesArr[i].entityType,RequiredAttendeesArr[i].id,cols);
if(retrievedparty.attributes[atr] != null) requiredattendeeemails = requiredattendeeemails + retrievedparty.attributes[atr].value + ";";
 
}
}

//get optional attendees
 
 
 

if(Xrm.Page.getAttribute("optionalattendees").getValue() != null)
 
{

var OptionalAttendeesArr= new Array;
OptionalAttendeesArr = Xrm.Page.getAttribute("optionalattendees").getValue();
for (i = 0; i <= OptionalAttendeesArr.length -1; i++)
 
{
switch(OptionalAttendeesArr[i].entityType)
{

case "equipment":
var cols = ["emailaddress"];
var atr = "emailaddress";
break;
case "systemuser":
var cols = ["internalemailaddress"];
var atr = "internalemailaddress";
break;
default:
var cols = ["emailaddress1"];
var atr = "emailaddress1";
break;
 
}

var retrievedparty = XrmServiceToolkit.Soap.Retrieve(OptionalAttendeesArr[i].entityType,OptionalAttendeesArr[i].id,cols);
if(retrievedparty.attributes[atr] != null) optionalattendeeemails = optionalattendeeemails + retrievedparty.attributes[atr].value + ";";
 
}
}

//---------------------------------------------------
 
 
//alert("here");
//create active x object, IE permissions must be set to trust this from this secure site, if not, you will get an error
 

objOL = new ActiveXObject("Outlook.Application");
 

//inform user that Outlook meeting request is being created
alert("Outlook meeting request will be created, click ''send invites'' to send invites to recipients");
 

//fill in values, note that dates need to be formatted appropriately
objappt = objOL.CreateItem(olAppointmentItem);
 

objappt.Subject = (Xrm.Page.getAttribute("subject").getValue()==null) ? "" : Xrm.Page.getAttribute("subject").getValue();
 

objappt.Start = Xrm.Page.getAttribute("scheduledstart").getValue().toFormattedString("mm/dd/yyyy hh:MM APM");
objappt.End = Xrm.Page.getAttribute("scheduledend").getValue().toFormattedString("mm/dd/yyyy hh:MM APM");
// objappt.Start = Xrm.Page.getAttribute("scheduledstart").getValue();
 
 
//objappt.End = Xrm.Page.getAttribute("scheduledend").getValue();
 

objappt.MeetingStatus = olMeeting;
//objappt.Location = Xrm.Page.getAttribute("location").getValue();
 
 
 

objappt.Location = (Xrm.Page.getAttribute("location").getValue()==null) ? "" : Xrm.Page.getAttribute("location").getValue();
 

//objappt.Body = Xrm.Page.getAttribute("description").getValue();
objappt.Body = (Xrm.Page.getAttribute("description").getValue()==null) ? "" : Xrm.Page.getAttribute("description").getValue();
//alert(requiredattendeeemails);
 
 
//alert(requiredattendeeemails.length());
 

if(requiredattendeeemails != "") objappt.RequiredAttendees = requiredattendeeemails;
if(optionalattendeeemails != "") objappt.OptionalAttendees = optionalattendeeemails;
 
objappt.Display();

objAppt = null;
objOL = null
Xrm.Page.getAttribute("rxrm_sendmeetinginvites").setValue(false);
 
}

catch (err)
 
{

//in the event of an error, most likely active x related.
alert("You will need to set your IE security settings to a enable or prompt ''Initialize and script ActiveX controls not marked as safe for scripting.'' for the trusted zone of this CRM server in order for Outlook to create meeting invites.");
 
}
}
};
//date functions, credit to Adi Katz from http://mscrm4ever.blogspot.ca/2009/09/formatting-crm-datetime-field.html
 
 

Date.prototype.toFormattedString = function(format)
 
{

var d = this;
var f = "";
 
f = f + format.replace( /dd|mm|yyyy|MM|hh|ss|ms|APM|\s|\/|\-|,|\./ig ,

function match()
 
{

switch(arguments[0])
 
{

case "dd":
var dd = d.getDate();
return (dd < 10)? "0" + dd : dd;
case "mm":
var mm = d.getMonth() + 1;
return (mm < 10)? "0" + mm : mm;
case "yyyy": return d.getFullYear();
case "hh":
var hh = d.getHours();
return (hh < 10)? "0" + hh : hh;
case "MM":
var MM = d.getMinutes();
return (MM < 10)? "0" + MM : MM;
case "ss":
var ss = d.getSeconds();
return (ss < 10)? "0" + ss : ss;
case "ms": return d.getMilliseconds();
case "APM":
var apm = d.getHours();
return (apm < 12)? "AM" : "PM";
default: return arguments[0];
 
}
});

return f;
 
}

Thursday, April 11, 2013

Enable prefiltering on FetchXML report

I just spent over an hour trying to understand why, all of sudden, something I've always done a certain way seems to NOT work anymore. Ever been there?

I was working on a CRM 2011 report (FetchXML) that I want prefiltered to pick up the selected Invoice records. Should be easy enough, simply add enableprefiltering="true" to the main entity to filter. Right?

Or is it?

For some reason (I was probably recycling a query from somewhere else, as I tend to do), I had given my entity an alias: <entity name="invoice" alias="Inv" enableprefiltering="true" >. The report uploaded to CRM without a hitch, the prefilter ("Advanced Find"-like window) came up to allow me to select filter criteria, but no matter the conditions, the report would NOT filter.

After trying various other options (including eating an ice cream bar, which did nothing for my report performance but made me happier), I removed the alias and ta-da! the filter suddenly works.

You might want to give this a try if you are facing the same issue in a similar context. (I haven't tried to replicate the solution without the ice cream element, so take no chance and go get one!)

~ Brigitte