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.