Recurring Service Cases

We recently updated our CRM solution for automatically creating recurring service cases. We use recurring service cases to automatically schedule items for our customers that have signed up for managed services or that are under some form of retainer.


 


I originally implemented this in CRM 1.2 using CRM using special products in our CRM product catalog to represent each service offering. For example we had a product item the corresponded to Server Patch Management and another that corresponded to UPS system check, etc. Each product was related to a maintenance item that was defined in an XML configuration file. The maintenance item contained all the information need to create a service case as well as scheduling information (e.g. 1st and 15th of the month, 2nd Tuesday of the month, 90 days since last completion, etc.)


 


I created an ASP.NET web service that contained the code to make it all work. When the web service was called it would look through all active CRM Contracts and examine each contract line item to see if the contract line item was for one of our recurring maintenance tasks. If so the code determined if it was time to schedule a new service case and created the case if required. A simple VBScript executed by the Windows scheduler (an often overlooked tool) called the web service daily. It wasn’t elegant but it worked for almost a year and ensured we did not drop the ball on our contractual obligations.


 


Custom entities in CRM 3.0 have really allowed us to refine this solution. Richard Riddle, one of our CRM developers, took what I had started with and helped me make a much richer and more robust product. We made significant changes in the architecture of the solution by removing all of the complexity of the XML configuration files and placing all of the information on scheduling and product catalog relationships in a new custom entity that we call Maintenance Items. We also implemented the concept of a template service case that makes it much easier to control what information goes into the service cases that are scheduled automatically. Lastly we replaced the ASP.NET web service and Windows schedule with a new Windows Service.


 


The new system is much easier to configure and gives us greater flexibility. For example we can now have several recurring services associated with one product SKU. This makes it much easier to package our services in the product catalog and makes our CRM Contracts much more readable. So with a little code and a custom entity Microsoft CRM is now capable of scheduling an unlimited number of recurring service cases based on the contracts we negotiate with our customers. 

9 thoughts on “Recurring Service Cases”

  1. I’d really like to have this solution for my internal CRM deployment. Is any of this available for a deeper inspection?

  2. We are thinking about re-writing this stuff and making it available. The problem we have now is that the code is very much tied to specifiec fields we created in CRM back on version 1.2. We need to re-design this to make it a bit more generic for implementation. For example our code identified a template service case as the newest service case connected to a contract where the service case is cancelled and hte casetypecode = 5. It works great for us but other implementation my already be using casetypecode 5 for some other purpose.

    It seems like there is some interest so we will fit it in when time permits.

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

    I have done one implementation for creating reoccuring 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 = "” +
    " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
    " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>“+
    authenticationHeader+
    “+
    “+
    “+
    “+subject+”“+
    “+serviceid+”“+
    “+ownerId+”“+
    “+
    “+
    account“+
    “+customerId+”“+
    11“+
    “+
    “+
    “+
    “+
    systemuser“+
    “+resourceId+”“+
    1“+
    “+
    “+
    “+startUTC+”“+
    “+endUTC+”“+
    “+recurringEndUTC+”“+
    “+new_recurringactivity+”“+
    “+
    “+
    “+
    “;
    // 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

    “+
    “+
    systemuser“+
    “+resourceId+”“+
    1“+
    “+
    “+

    If you are considering equipments as your resources then use

    systemuser“+

    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.

    Regards,

    Sarbashish Bhattacharjee

  4. Yes it is easy to get confused if you are seek for one single formula for blogging reputation. Different professionals give different pieces of benefit and many explode one another. For example students get a very good chance to type buy term papers and get assistance.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>