Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Change WorkOrder Incident type

(0) ShareShare
ReportReport
Posted on by 2,909

Hi,

I am trying to solve what I presume will be quite common need.

In Field Service we have Customer Assets and Service Accounts.

We have routine maintenance bookings on either monthly, bi-monthly, quarterly or half yearly recurrence for customer assets. 

We also need to have one annual maintenance booking and in turn cancel the normal booking so a monthly would have 11 normal and one annual booking. The difference is the annual has extra service tasks compared to a normal booking

The easy way I see to solve this is have a normal and a annual booking setup and when it's created do a lookup of normal bookings and cancel / delete the normal booking. If the agreements are setup with the same recurrence start date this is quite simple as they will both fall on the same date. This also carries a risk if the plugin runs before the normal booking is generated.

The problem in this instance is that the anniversary date (agreement) and booking (recurrence start date) are different and the anniversary should drive the annual date i.e. 12 months from anniversary. To change the recurrence start date can be done however it's over 500 assets which I can do relatively easily through ssis however as it's production would preferably not just in case it causes issues.

My next idea was to have a plugin:

Set to pre create of workorder

Check is maintenance work order

Look up agreement start date

Check agreement start date against booking date with something like this:

                            EntityReference agreementID = entity.GetAttributeValue<EntityReference>("msdyn_agreementid");
                            Entity agreement = service.Retrieve("msdyn_agreement", agreementID.Id, new ColumnSet("msdyn_startdate", "eye_visits"));
                            DateTime startDate = ((DateTime)agreement["msdyn_startdate"]).Date;
                            int visits = (int)agreement["eye_visits"];
                            DateTime today = DateTime.Today.Date;
                            int days = (int)((today - startDate).TotalDays);
                            bool annual = false;
                            if (visits == 12)
                               if ((days <= 365) && (days >= 334))
                               annual = true;
                            else if (visits == 6)
                                if ((days <= 364) && (days >= 305))
                                    annual = true;
                                else if (visits == 4)
                                    if ((days <= 365) && (days >= 273))
                                        annual = true;
                                    else if (visits == 2)
                                        if ((days <= 365) && (days >= 183))
                                            annual = true;
                                        else
                                            annual = false;
If annual = true

Get entityreference from msdyn_primaryincidenttype to msdyn_incidenttype

Update msdyn_incidenttype to annual incident type

Hopefully this would work and populate with correct service tasks. I'm a little concerned whether it may still get updated / overwritten after this by agreementbookingincident entity.

I would just change on Post Create however the Incidentype to workorder service task is referential so would need to delete existing service tasks, update incident type.

Not far off testing in a sandbox however was just after some thoughts or ideas!

*This post is locked for comments

  • Suggested answer
    antc Profile Picture
    antc 2,909 on at
    RE: Change WorkOrder Incident type

    After lots of testing I have decided best way forward is to have two Agreement bookings one annual and one normal maintenance.

    I was going to have the recurrence booking date for the annual one day after the normal recurrence booking date to ensure that the booking dates had been processed prior to code running to look for normal booking duplicate date and cancel it. 

    Cons with this method is that it if set to run on booking date (create) that has incident type annual and a change is made to normal booking recurrence schedule the canceled booking will come back as they get recreated on any change.

    Also if the recurrence start date is the same day as the scheduled booking date and you make the second agreement one day later they will not line up and the coinciding bookings will be one month apart.

    i.e.

    Scheduled Booking Date is 2nd Wednesday of the Month

    Normal Maintenance 

    <root><pattern><period>monthly</period><option>everyWeekday</option><months every='2'><weekdef>2</weekdef><weekday>3</weekday></months></pattern><range><start>05/10/2017</start>

    Annual Booking

    <root><pattern><period>monthly</period><option>everyWeekday</option><months every='12'><weekdef>2</weekdef><weekday>3</weekday></months></pattern><range><start>05/9/2017</start>

    The 2nd Wednesday in May 2017 is on the 9th so the normal booking will be a month later than the coinciding Annual booking. The recurrence is based on the recurrence pattern and the range of recurrence start date.

    5277.Capture.PNG

    The most efficient method I can think of is to have a batch job that runs say weekly and fetches bookings that have an Incident Type of Annual and run the logic on that:

    Retrieve related normal booking.

    If booking exists cancel related normal booking.

  • Suggested answer
    antc Profile Picture
    antc 2,909 on at
    RE: Change WorkOrder Incident type

    Still trying to work out where the system adds the Incident Type!

    However after testing in console programs this code will remove the Incident type and all related Service Tasks from a Work Order. For now will likely use this on Post Create asynchronous. Another plugin is adding the Annual Incident type on create so will merge them together.

    using System.Configuration;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Tooling.Connector;
    using System.Collections;
    using Microsoft.Xrm.Sdk.Query;
    using System;
    using System.Linq;
    
    namespace LearnCRM
    {
        class Program
        {
            static void Main(string[] args)
            {
                CrmServiceClient Conn = new CrmServiceClient(ConfigurationManager.ConnectionStrings["CRM"].ConnectionString);
                IOrganizationService service = Conn.OrganizationServiceProxy;
    
                // Gets WO GUID not needed in plugin only console
                QueryByAttribute query = new QueryByAttribute { EntityName = "msdyn_workorder", ColumnSet = new ColumnSet("msdyn_name") };
                query.AddAttributeValue("msdyn_name", "WO-10238");
                var workorderID = service.RetrieveMultiple(query).Entities.FirstOrDefault();
    
                // Gets Incident type GUID for normal Maintenance, replace AllComuns = True
                QueryExpression query5 = new QueryExpression() { };
                query5.EntityName = "msdyn_workorderincident";
                query5.ColumnSet.AllColumns = true;
                query5.Criteria.AddCondition("msdyn_workorder", ConditionOperator.Equal, workorderID.Id);
                query5.Criteria.AddCondition("msdyn_name", ConditionOperator.Equal, "Maintenance - Traction");
                // EntityCollection incidenttype2 = service.RetrieveMultiple(query5);
                Guid incidentType = service.RetrieveMultiple(query5).Entities.FirstOrDefault().Id;
    
                // Retreive all related Incident Types by using Workorder Guid, replace AllComuns = True
                QueryExpression query2 = new QueryExpression() { };
                query2.EntityName = "msdyn_workorderincident";
                query2.ColumnSet.AllColumns = true;
                query2.Criteria.AddCondition("msdyn_workorder", ConditionOperator.Equal, workorderID.Id);
                EntityCollection retrievedWorkOrders = service.RetrieveMultiple(query2);
                foreach (var a in retrievedWorkOrders.Entities)
                {
                    // Check if Workorder is normal Maintinance Incident Type
                    if (a.GetAttributeValue<string>("msdyn_name").StartsWith("Maintinance"))
                    {
                        // Retrieve all Service Tasks that are for normal Matinance Work Order
                        QueryExpression query4 = new QueryExpression() { };
                        query4.EntityName = "msdyn_workorderservicetask";
                        query4.ColumnSet.AllColumns = true;
                        query4.Criteria.AddCondition("msdyn_workorder", ConditionOperator.Equal, workorderID.Id);
                        query4.Criteria.AddCondition("msdyn_workorderincident", ConditionOperator.Equal, incidentType);
                        EntityCollection retrieved3 = service.RetrieveMultiple(query4);
    
                        // Loop through all retrieved Service Task records and delete
                        foreach (var c in retrieved3.Entities)
                        {
                                service.Delete("msdyn_workorderservicetask", c.Id);
                        }
                        // Then set the lookup to the normal Maintinance task to null
                        a["msdyn_workorder"] = null;
                        service.Update(a);
                    }
                    else
                        Console.WriteLine("This is not: " + a.GetAttributeValue<string>("msdyn_name"));
                }
            }
        }
    }
  • antc Profile Picture
    antc 2,909 on at
    RE: Change WorkOrder Incident type

    Any clues how?

    I can update via plugin and get it to populate the Annual maintenance type and service tasks however I presume (MSDYN_FIELDSERVICESYSTEMACTION) or similar is at some stage adding the normal maintenance Incident type as well and all of it's service tasks.

    I am trying to work out where it's adding the normal maintenance task so I can try to update null then update with annual.

  • Suggested answer
    RE: Change WorkOrder Incident type

    Hello,

    You can go with custom workflow or ms flow.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Daivat Vartak – Community Spotlight

We are honored to recognize Daivat Vartak as our March 2025 Community…

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Kudos to the February Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,516 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,409 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans