Wednesday, April 22, 2015

Timer Job to Start the workflow in a list

Recently, I had an interesting requirement. No of list contains items and they expire on certain dates and require to send reminders for each items.  Initially I thought to write a custom workflow and kick the workflow by the OOB expiration policy/information policy. However information policy check dates are above the specified date. Example: anything more than 7 years.  So if you set the workflow to kick, it’s going to kick again and again for any items which are more than 7 years. Especially you won’t prefer to send email more than once. So I come up with a timer job for that.
The timer job will read a central list, which has details of list that need to run the expire workflow, and then kick the workflow.
Here is the sample of that list.


Then I create a timer job.
Here is the code for that.

namespace SP.Sample.OnlineForms
{
    using System;
    using System.Collections.Generic;
    using System.Web;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Workflow;
    using Microsoft.SharePoint.WorkflowUtil;
    using Microsoft.SharePoint.Utilities;
    using System.Security.Permissions;
    using System.Text;
    using System.Collections.Specialized;

    public class SampleExpireAlertsTimerJob : SPJobDefinition
    {
        //SPWeb mySiteWeb;

        public SampleExpireAlertsTimerJob(SPWebApplication webApp)
            : base("Sample Expire Alerts", webApp, null, SPJobLockType.Job)
        {
            this.Title = "Sample Expire Alerts";
        }
        public SampleExpireAlertsTimerJob()
            : base()
        {
        }
        public override void Execute(Guid targetInstanceId)
        {
            string key = "TeamsRootSiteUrl";
            string TeamsRootSiteUrl = "";
            if (this.Properties.Contains(key))
            {
                TeamsRootSiteUrl = this.Properties[key].ToString();
               
            }

            if (!string.IsNullOrEmpty(TeamsRootSiteUrl))
            {

               

                using (SPSite site = new SPSite(TeamsRootSiteUrl))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPList list = web.Lists.TryGetList("SampleExpireAlerts");
                        SPQuery oQuery = new SPQuery();

                        oQuery.Query = string.Format(@"
                                                <OrderBy><FieldRef Name='ID' /></OrderBy>"
                                              );
                        SPListItemCollection collListItems = list.GetItems(oQuery);

                        foreach (SPListItem item in collListItems)
                        {
                            string weburl = item["WebURL"] as string;
                            string listName = item["ListName"] as string;
                            string dateFieldtoFilter = item["DateFieldtoFilter"] as string;
                            int daysToFilter = int.Parse(item["DaysToFilter"] as string);
                            string workflowName = item["WorkflowName"] as string;

                            StartAlertWorkFlow(weburl, listName, dateFieldtoFilter, daysToFilter, workflowName);

                        }
                    }
                }
            }
        }

        /// <summary>
        /// Send remainder and warning emails to the employees
        /// </summary>
        /// <param name="employeeName">Name of the employee ex: Sutha Thavaratnarajah</param>
        /// <param name="moduleName">Name of the module ex: conduct</param>
        /// <param name="TeamsRootSiteUrl"> Url retrived from the timer job property.</param>
        /// <param name="eid">email template ID.</param>
        public void StartAlertWorkFlow(string weburl, string listName, string dateFieldtoFilter, int daysToFilter, string workflowName)
        {
            using (SPSite SampleSite = new SPSite(weburl))
            {
                using (SPWeb SampleWeb = SampleSite.OpenWeb())
                {

                    SPList list = SampleWeb.Lists.TryGetList(listName);
                    SPQuery oQuery = new SPQuery();
                    //string userName = "Sutha Thavaratnarajah";
                    string datetofilter = System.DateTime.Today.AddDays(daysToFilter).ToString("yyyy-MM-dd");

                    oQuery.Query = string.Format(@"
                                                    <Where>
                                                      <Eq>
                                                         <FieldRef Name='{0}' />
                                                         <Value IncludeTimeValue='False' Type='DateTime'>{1}</Value>
                                                      </Eq>
                                                   </Where>", dateFieldtoFilter, datetofilter);
                    SPListItemCollection collListItems = list.GetItems(oQuery);
                    foreach (SPListItem item in collListItems)
                    {

                        item.Web.AllowUnsafeUpdates = true;
                        SPWorkflowManager workflowManager = item.Web.Site.WorkflowManager;
                        SPWorkflowAssociationCollection workflowAssociation = item.ContentType.WorkflowAssociations;
                        foreach (SPWorkflowAssociation Association in workflowAssociation)
                        {
                            if (Association.Name == workflowName)
                            {
                                workflowManager.StartWorkflow(item, Association, Association.AssociationData, true);
                                break;
                            }
                        }

                   

                    }
                  
                }
            }
        }
    }
}

So, this timer job will kick the specified workflow in specified List with the given criteria.


Note: you need to create the workflow in the target lists.

No comments:

Post a Comment