views:

244

answers:

2

It doesn't look like Dynamics allows for recurring appointments. I found a tutorial for recurring service activities, but I don't really follow the portion where it sends a SOAP object. If anyone can help I would appreciate it

+1  A: 

This could be done thru a Workflow, by creating an activity on a specific interval, or under specific condition... There is no recurring appointment in CRM itself.

Another workaround may be to schedule the Appointment via the Outlook client, and synchronize the client with CRM, but I didn't test this solution.

Mercure Integration
A: 

It is possible to create reccuring appointments in MS CRM 4.0 without using workflow.

I have done one implementation for creating reccuring service activity. I have added two new fields in the Service Activity entity. Please read the detailed implementation below:

Entity Name: serviceappointment

Add two new Fields

New Field 1

Field Label: Recurring Frequency Field Name: new_recurringactivity Requirement Level: No Constraint Field TYpe: picklist Field Values:

1 - Daily 2 - Weekly 3 - Fortnightly 4 - Monthly 5 - Bi-Monthly 6 - Quarterly 7 - Half Yearly 8 - Yearly

New Field 2

Field Label: Recurring End Date Field Name: new_recurringenddate Field Type: datetime Field Format: Date Only Requirement Level: No Constraint

Purpose of the new fields

Field Name: new_recurringactivity Purpose: This field will accept recurring frequency from the user.

Field Name: new_recurringenddate Purpose: This field will accept the date from the user. It will not create any activity beyond the date. Otherwise it will go in a endless loop.

CODE SNIPPET 1

// Add this code snippet to the OnLoad event of the Service Activity Form

// Lock the recurring Service Activiy fields once activities have been created
if (crmForm.all.new_recurringactivity.DataValue)
{
crmForm.all.new_recurringactivity.disabled = true;
crmForm.all.new_recurringenddate.disabled = true;
}

CODE SNIPPET 2

// Add this code snippet to the OnSave event of the Service Activity

// Function to format a date to the UTC format required by web services
function DateToUTCFormat(inputDate)
{
var date = inputDate.getDate();
var month = inputDate.getMonth()+1;
var year = inputDate.getYear();
var hours = inputDate.getHours();
var minutes = inputDate.getMinutes();
var ampm = " AM";
if (hours > 11)
    {
    ampm = " PM";
    hours = hours - 12;
    }
if (hours == 0)
    {hours = 12;}
if (minutes < 10)
    {var time = hours.toString() + ":0" + minutes.toString() + ":00" + ampm;}
else
    {var time = hours.toString() + ":" + minutes.toString() + ":00" + ampm;}
var UTCDate = month.toString() + "/" + date.toString() + "/" + year.toString() + " " + time;
return UTCDate;
}


if (crmForm.all.new_recurringactivity.disabled == false && crmForm.all.new_recurringactivity.DataValue && crmForm.all.new_recurringactivity.DataValue)

{
var interval = 0;
switch (parseInt(crmForm.all.new_recurringactivity.DataValue)) 
{
case 1:   // Daily (Please check the value you are getting from the CRM Form)
 interval = 1;
 break;

case 2: // weekly
 interval = 7;
 break;

case 3: // Fortnightly
 interval = 14;
 break;

case 4: // Monthly
 interval = 30;
 break;

case 5: // Bi-Monthly
 interval = 60;
 break;

case 6: // Quarterly
 interval = 90;
 break;

case 7: // Half Yearly
 interval = 180;
 break;

case 8: // Yearly
 interval = 365;
 break;

}

var recurringEnd = crmForm.all.new_recurringenddate.DataValue;
recurringEnd.setDate(recurringEnd.getDate()+1);
var activityStart = crmForm.all.scheduledstart.DataValue;
var activityEnd = crmForm.all.scheduledend.DataValue;

// Set the first reccuring appointment as per the recurring frequency opted by the user

activityStart.setDate(activityStart.getDate()+interval);
activityEnd.setDate(activityEnd.getDate()+interval);

// Prepare values for the new Service Activity

var subject = crmForm.all.subject.DataValue;
var regardingId = crmForm.all.regardingobjectid.DataValue[0].id;
var customerId = crmForm.all.customers.DataValue[0].id;
var serviceid = crmForm.all.serviceid.DataValue[0].id;
var resourceId = crmForm.all.resources.DataValue[0].id;
var ownerId = crmForm.all.ownerid.DataValue[0].id;
var new_recurringactivity = crmForm.all.new_recurringactivity.DataValue;

// Loop for the number of recurring Service Activities
while (activityStart < recurringEnd)
    {    
    // Prepare the SOAP message.
    var startUTC = DateToUTCFormat(activityStart);
    var endUTC = DateToUTCFormat(activityEnd);
   // alert("startUTC: "+startUTC);
    var recurringEndUTC = DateToUTCFormat(recurringEnd);
    var authenticationHeader = GenerateAuthenticationHeader();
    var xml = "<?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'&gt;"+ 
    authenticationHeader+
    "<soap:Body>"+ 
    "<Create xmlns='http://schemas.microsoft.com/crm/2007/WebServices'&gt;"+ 
    "<entity xsi:type='serviceappointment'>"+
    "<subject>"+subject+"</subject>"+
    "<serviceid>"+serviceid+"</serviceid>"+
    "<ownerid>"+ownerId+"</ownerid>"+
    "<customers>"+
        "<activityparty>"+
            "<partyobjecttypecode>account</partyobjecttypecode>"+
            "<partyid>"+customerId+"</partyid>"+
            "<participationtypemask>11</participationtypemask>"+
        "</activityparty>"+
    "</customers>"+
    "<resources>"+
        "<activityparty>"+
            "<partyobjecttypecode>systemuser</partyobjecttypecode>"+
            "<partyid>"+resourceId+"</partyid>"+
            "<participationtypemask>1</participationtypemask>"+
        "</activityparty>"+
    "</resources>"+
    "<scheduledstart>"+startUTC+"</scheduledstart>"+
    "<scheduledend>"+endUTC+"</scheduledend>"+
    "<new_recurringenddate>"+recurringEndUTC+"</new_recurringenddate>"+
    "<new_recurringactivity>"+new_recurringactivity+"</new_recurringactivity>"+
    "</entity>"+ 
    "</Create>"+ 
    "</soap:Body>"+ 
    "</soap:Envelope>";
    // Prepare the xmlHttpObject and send the request.
    var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
    xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
    xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Create");
    xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xHReq.setRequestHeader("Content-Length", xml.length);
    xHReq.send(xml);
    // Capture the result
    var resultXml = xHReq.responseXML;

    // Check for errors.
    var errorCount = resultXml.selectNodes('//error').length;
    if (errorCount != 0)
        {
         var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
         alert(msg);
        }
    // Notify user of Service Activity creation
    else
        {
       // alert("Service Activity created on " + activityStart);
        }
    // Increment the next Service Actvity to be created by as per the recurring frequency opted by the user
    activityStart.setDate(activityStart.getDate()+interval);
    activityEnd.setDate(activityEnd.getDate()+interval);
    }

} // Code block Ends

Some More Explanation

Please note in the above code snippet I am taking resources as user. So for that I have used in the code snippet

"<resources>"+
        "<activityparty>"+
            "<partyobjecttypecode>systemuser</partyobjecttypecode>"+
            "<partyid>"+resourceId+"</partyid>"+
            "<participationtypemask>1</participationtypemask>"+
        "</activityparty>"+
    "</resources>"+

If you are considering equipments as your resources then use

"<partyobjecttypecode>systemuser</partyobjecttypecode>"+

Also note that if you want to accept multiple resources then you need to change the value in the "participationtypemask" node.

Since I am expecting 1 resource so I have kept the value as 1.

Let me know if this helps.

If you can't see the code properly then you can also visit http://social.microsoft.com/forums/en-US/crmdevelopment/thread/3f020e02-cd86-44b2-9cff-36e6cdafc8d8/

Regards,

Sarbashish Bhattacharjee

Sarbashish Bhattacharjee
This worked for me. I just had to add some exception handling for the javascript in case the user did not set the regarding, customer, or parent parameters.
true