/// <summary>
 /// perform some actions for this workflow definition
 /// </summary>
 /// <param name="documentStore">The related org store</param>
 /// <param name="initiator">The entity that initiated the workflow (e.g. a sickness or leave)</param>
 /// <param name="actions"></param>
 public void PerformActions(IDocumentStore documentStore, WorkflowInitiator initiator, List<WorkflowHandlerAction> actions)
 {
     foreach (var action in actions)
     {
         PerformAction(documentStore, initiator, action);
     }
 }
        /// <summary>
        /// trigger the handling of an event by the workflow. 
        /// </summary>
        /// <param name="documentStore"></param>
        /// <param name="initiator">the workflow initiator process</param>
        /// <param name="objectType">The object type that has raised the event</param>
        /// <param name="eventType">The type of event on that object</param>
        /// <param name="trigger">The actual object that raised the event in the first place</param>
        public virtual void HandleEvent(IDocumentStore documentStore, WorkflowInitiator initiator, string objectType, string eventType, object trigger)
        {
            //get the relevant event handlers for this event
            var handlers = EventHandlers.Where(h => h.ObjectType == objectType && h.EventType == eventType);

            List<dynamic> children; 
            using (var session = documentStore.OpenSession())
            {
                //get child items for the process.
                children = session.Query<AllItemsById.Result, AllItemsById>()
                        .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                       .Where(i => i.ParentId == initiator.Id)
                       .As<dynamic>()
                       //.OfType<IWorkflowItem>()
                       .ToList();

                //var test = session.Query<Task>().Where(t => t.ParentItemId == initiator.Id).FirstOrDefault(); 

            }
            //for each handler, Handle it and perform resultant actions. 
            foreach (var handler in handlers)
            {
                var actions = handler.Handle(new WorkflowInitiatorPlus{Initiator = initiator, Children = children}, trigger);
                PerformActions(documentStore, initiator, actions);
            }
        }
 public override void PerformAction(IDocumentStore documentStore, WorkflowInitiator triggerprocess, WorkflowHandlerAction action)
 {
     //do nothing?
     (triggerprocess as TestInitiator).ActionsPerformed.Add(action);
 }
 public abstract void PerformAction(IDocumentStore documentStore, WorkflowInitiator triggerprocess, WorkflowHandlerAction action);
        /// <summary>
        /// perform an action on the leave process
        /// </summary>
        /// <param name="documentStore">The RavenDB document store to be used</param>
        /// <param name="triggerprocess">The initiator process - e.g. leave or sickness</param>
        /// <param name="action">The action to be performed</param>
        public override void PerformAction(IDocumentStore documentStore,
                                            WorkflowInitiator triggerprocess,
                                           WorkflowHandlerAction action)
        {
            //we know its a Leave so cast it to the correct type
            var leave = (Leave) triggerprocess;

            switch (action.Action) //depending on the type of action do different things
            {
                case WorkflowHandlerAction.Actions.AddTask: //add a task
                    //what am I creating?
                    var actionmodel = action.DeserialiseObject<CreateProcessTaskActionModel>();

                    //need to convert the actionmodel into an event.
                    var newtask = new Task
                                      {
                                          Id = IlluminateDatabase.GenerateId<Task>(),
                                          Type = new TaskType {Name = actionmodel.TaskName},
                                          AssignedRoles =
                                              (from role in actionmodel.AssignedRoles select Role.GetRole(role)).ToList(),
                                          DueDate = actionmodel.DueDate,
                                          ConsolidatedCompletionDate = actionmodel.DueDate,
                                          CreatedBy = leave.UserCreatedProcess,
                                          Title = actionmodel.Title,
                                          Description = actionmodel.Description,
                                          ParentItemId = leave.Id
                                      };
                    using (var session = documentStore.OpenSession())
                    {
                        session.Store(newtask);
                        newtask.UpdateAssignees(session, leave.Subject.UserId);
                        session.SaveChanges();
                    }

                    break;
                case WorkflowHandlerAction.Actions.AddMeeting: //add a meeting

                    var meetingactionmodel = action.DeserialiseObject<CreateProcessMeetingActionModel>();

                    //need to convert the actionmodel into an event. but problem is looking up user?
                    var newMeeting = new Meeting
                                         {
                                             Id = IlluminateDatabase.GenerateId<Meeting>(),
                                             Type = new TaskType {Name = meetingactionmodel.TaskName},
                                             AssignedRoles =
                                                 (from role in meetingactionmodel.AssignedRoles
                                                  select Role.GetRole(role)).ToList(),
                                             Invitees = new List<Invitee> {Invitee.FromSimpleUser(leave.Subject)},
                                             DueDate = meetingactionmodel.DueDate,
                                             ConsolidatedCompletionDate = meetingactionmodel.DueDate,
                                             CreatedBy = leave.UserCreatedProcess,
                                             Title = meetingactionmodel.Title,
                                             Description = meetingactionmodel.Description,
                                             ParentItemId = leave.Id,
                                             DurationMinutes = 30
                                         };
                    //now save the new mmeeting
                    using (var session = documentStore.OpenSession())
                    {
                        session.Store(newMeeting);
                        newMeeting.UpdateAssignees(session, leave.Subject.UserId);
                        session.SaveChanges();
                    }

                    break;
                case WorkflowHandlerAction.Actions.DeleteTask: //delete scheduled a task

                    using (var session = documentStore.OpenSession())
                    {
                        var task = session.Load<Task>(action.Value);
                        session.Delete(task);
                        session.SaveChanges();
                    }
                    break;
                case WorkflowHandlerAction.Actions.DeleteMeeting: //delete a scheduled meeting
                    using (var session = documentStore.OpenSession())
                    {
                        var meeting = session.Load<Meeting>(action.Value);
                        session.Delete(meeting);
                        session.SaveChanges();
                    }
                    break;
            }
        }
        /// <summary>
        /// Perform an action on the default sickness workflow
        /// </summary>
        /// <param name="documentStore">The document store to use</param>
        /// <param name="triggerprocess">The workflow initiator that triggered this</param>
        /// <param name="action">The action to be performed</param>
        public override void PerformAction(IDocumentStore documentStore, WorkflowInitiator triggerprocess, WorkflowHandlerAction action)
        {
            var sickness = (Sickness) triggerprocess; //we know its a sickness so cast to it

            switch (action.Action) //depending on the action type act accordingly
            {
                case WorkflowHandlerAction.Actions.AddTask:
                    //what am I creating? - deserialise the contents of the action
                    var actionModel = action.DeserialiseObject<CreateProcessTaskActionModel>();

                    //need to convert the actionmodel into an event - in this case a task
                    var newtask = new Task
                                        {
                                            Id = IlluminateDatabase.GenerateId<Task>(),
                                            Type = new TaskType {Name = actionModel.TaskName},
                                            AssignedRoles = (from role in actionModel.AssignedRoles select Role.GetRole(role)).ToList(),
                                            DueDate = actionModel.DueDate,
                                            ConsolidatedCompletionDate = actionModel.DueDate>=DateTime.Now ? actionModel.DueDate : DateTime.Now,
                                            CreatedBy = sickness.UserCreatedProcess,
                                            Title =string.Format( actionModel.Title,sickness.Subject.FullName),
                                            Description = string.Format( actionModel.Description,sickness.Subject.FullName),
                                            ParentItemId = sickness.Id
                                        };
                    //store the task in the db
                    using (var session = documentStore.OpenSession())
                    {
                        session.Store(newtask);
                        newtask.UpdateAssignees(session, sickness.Subject.UserId);
                        session.SaveChanges();
                    }
                    
                    break;
                case WorkflowHandlerAction.Actions.AddMeeting:
   
                    var meetingactionmodel = action.DeserialiseObject<CreateProcessMeetingActionModel>();

                    //need to convert the actionmodel into an event. but problem is looking up user?
                    var newmeeting = new Meeting
                    {
                        Id = IlluminateDatabase.GenerateId<Meeting>(),
                        Type = new TaskType { Name = meetingactionmodel.TaskName },
                        AssignedRoles = (from role in meetingactionmodel.AssignedRoles select Role.GetRole(role)).ToList(),
                        Invitees = new List<Invitee> { Invitee.FromSimpleUser(sickness.Subject)},
                        DueDate = meetingactionmodel.DueDate,
                        ConsolidatedCompletionDate = meetingactionmodel.DueDate >= DateTime.Now ? meetingactionmodel.DueDate : DateTime.Now,
                        CreatedBy = sickness.UserCreatedProcess,
                        Title = meetingactionmodel.Title,
                        Description = meetingactionmodel.Description,
                        ParentItemId = sickness.Id
                    };
                    //save the meeting in the DB
                    using (var session = documentStore.OpenSession())
                    {
                        session.Store(newmeeting);
                        newmeeting.UpdateAssignees(session, sickness.Subject.UserId);
                        session.SaveChanges();
                    }
       
                    break;
                case WorkflowHandlerAction.Actions.DeleteTask:
                    //delete the task from the DB
                    using (var session = documentStore.OpenSession())
                    {
                        var task = session.Load<Task>(action.Value);
                        session.Delete(task);
                        session.SaveChanges();
                    }
                    break;
                case WorkflowHandlerAction.Actions.DeleteMeeting:
                    //delete the meeting from the DB
                    using (var session = documentStore.OpenSession())
                    {
                        var meeting = session.Load<Meeting>(action.Value);
                        session.Delete(meeting);
                        session.SaveChanges();
                    }
                    break; 
                case WorkflowHandlerAction.Actions.NotifyActorsOfCreation:
                    using (var session = documentStore.OpenSession())
                    {
                        
                        var managerCreatedSickness=sickness.UserCreatedProcess.UserId==sickness.CurrentProcessOwner.UserId;
                        //if the manager created the sickness notify the employee 
                        Notification notification;
                        if (managerCreatedSickness)
                        {
                            notification = new Notification
                                               {
                                                   
                                                   NotificationRecipients = new[]
                                                                                {
                                                                                    new NotificationRecipient
                                                                                        {
                                                                                            NotificationDeliveryTypes =
                                                                                                NotificationDeliveryTypes
                                                                                                    .Email |
                                                                                                NotificationDeliveryTypes
                                                                                                    .Toast,
                                                                                            Users = new[]
                                                                                                        {
                                                                                                            sickness
                                                                                                                .Subject
                                                                                                        }
                                                                                        }
                                                                                },
                                                   Body =
                                                       string.Format(
                                                           "You have been registered as off sick for {0} by {1}",
                                                           sickness.SicknessReason.Name,
                                                           sickness.CurrentProcessOwner.FullName)

                                               };
                        }
                        else
                        {
                            notification = new Notification
                            {

                                NotificationRecipients = new[]
                                                                                {
                                                                                    new NotificationRecipient
                                                                                        {
                                                                                            NotificationDeliveryTypes =
                                                                                                NotificationDeliveryTypes
                                                                                                    .Email |
                                                                                                NotificationDeliveryTypes
                                                                                                    .Toast|
                                                                                                    NotificationDeliveryTypes.Sms,
                                                                                            Users = new[]
                                                                                                        {
                                                                                                            sickness.CurrentProcessOwner
                                                                                                        }
                                                                                        }
                                                                                },
                                Body =
                                    string.Format(
                                        "{0} has registered themselves as off sick for {1}.",
                                        sickness.Subject.FullName,
                                        sickness.SicknessReason.Name)

                            };
                        }
                        notification.Title = string.Format("Sickness for {0}", sickness.Subject.FullName);
                        notification.About = sickness.Subject;
                        notification.Id = IlluminateDatabase.GenerateId<Notification>();
                        notification.SendDate = DateTime.Now;

                        session.Store(notification);
                        session.SaveChanges();
                    }
                    break;

            }
        }