After a lot of hardship i have come up with workflow which does a very straight forward thing. it looks for an activity with a certain subject line. when it finds the activity in question, if the activity has not been cancelled, it cancels it after adding a note to it. i have done it for all the activity types. to avoid duplication i am just sticking with the first two (task and email). Since i'm copy-pasting, there is a chance that there will be unmatched parenthesis.
using System; using System.Collections.Generic; using System.Linq; using System.Text; //my usings using System.Activities; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Workflow; using Microsoft.Xrm.Sdk.Messages; using Microsoft.Xrm.Sdk.Query; using System.Collections.ObjectModel; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Deployment; using Microsoft.Xrm.Sdk.XmlNamespaces; using System.Activities.Debugger; using Microsoft.IdentityModel.Protocols.WSTrust; namespace Don_Det_onUpdate { public sealed class DonarDetailsOnApproved : CodeActivity { [Input("Type of Activity")] [RequiredArgument] [Default("4212")] [AttributeTarget("activitypointer","activitytypecode")] public InArgument TypeOfActivity { get; set; } [Input("Subject Line")] [RequiredArgument] public InArgument SubjectLine { get; set; } protected override void Execute(CodeActivityContext context) { IWorkflowContext con = context.GetExtension(); IOrganizationServiceFactory objIOrganizationServiceFactory = context.GetExtension(); IOrganizationService service = objIOrganizationServiceFactory.CreateOrganizationService(con.UserId); OptionSetValue ActType = TypeOfActivity.Get(context); try { var crm = new XrmServiceContext(service); Int16? ActivityId = Convert.ToInt16(ActType.Value); // 07 july by imran if (ActivityId.HasValue) { switch (ActivityId) { // this is a task... case 4212: var TaskList = crm.TaskSet.Where(t => t.Subject == SubjectLine.Get(context).ToString() && t.StateCode != TaskState.Canceled); foreach (Task tsk in TaskList) { var note = new Annotation { Subject = "System generated note", NoteText = "This activity is cancelled and no longer required.", ObjectId = new EntityReference(tsk.LogicalName, tsk.Id), ObjectTypeCode = tsk.GetType().ToString().ToLower() }; crm.AddObject(note); crm.UpdateObject(tsk); crm.SaveChanges(); var k = new SetStateRequest { EntityMoniker = new EntityReference(tsk.LogicalName, tsk.Id), State = new OptionSetValue(2), Status = new OptionSetValue(-1) }; crm.Execute(k); break; } break; case 4202: // email var EmailList = crm.EmailSet.Where(t => t.Subject == SubjectLine.Get(context).ToString() && t.StateCode != EmailState.Canceled); foreach (Email eml in EmailList) { var note = new Annotation { Subject = "System generated note", NoteText = "This activity is cancelled and no longer required.", ObjectId = new EntityReference(eml.LogicalName, eml.Id), ObjectTypeCode = eml.GetType().ToString().ToLower() }; crm.AddObject(note); crm.UpdateObject(eml); crm.SaveChanges(); var k = new SetStateRequest { EntityMoniker = new EntityReference(eml.LogicalName, eml.Id), State = new OptionSetValue(2), Status = new OptionSetValue(-1) }; crm.Execute(k); break; } break; default: break; } } } catch (Exception ex) { } } } }
the question that pops up as soon as you come across to the code. that how the hell you come across to the activitytype (which i used in switch). i am damn sure there are lots of smart ways to find them. but i debugged and looked for the value. (silly me...)