/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int howMany = dataMap.GetString("HowMany").AsIntegerOrNull() ?? 500000; var commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; bool anyRemaining = UpdateHistoryRecords(context, howMany, commandTimeout); if (!anyRemaining) { // Verify that there are not any history records that haven't been migrated using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = commandTimeout; if (!new HistoryService(rockContext) .Queryable() .Where(c => c.ChangeType == null) .Any()) { // delete job if there are no un-migrated history rows left var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } } }
public ServiceJob GetAddTestJob(JobNotificationStatus jobNotificationStatus = JobNotificationStatus.None) { var testJob = new ServiceJob { IsSystem = true, IsActive = true, Name = "Test Job", Description = "This job is used for testing RockJobListener", Class = "Rock.Tests.Integration.Jobs.RockJobListenerTestJob", CronExpression = "0 0 1 * * ?", NotificationStatus = jobNotificationStatus, Guid = "84AE12A7-968B-4D28-AB39-81D36D1F230E".AsGuid(), NotificationEmails = "*****@*****.**" }; using (var rockContext = new RockContext()) { var serviceJobService = new ServiceJobService(rockContext); var job = serviceJobService.Get(testJob.Guid); if (job != null) { testJobId = job.Id; return(job); } serviceJobService.Add(testJob); rockContext.SaveChanges(); } testJobId = testJob.Id; return(testJob); }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); ServiceJob job = jobService.Get(JobId); if (job != null) { try { // create a scheduler specific for the job var scheduleConfig = new System.Collections.Specialized.NameValueCollection(); var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40); scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName); var schedulerFactory = new StdSchedulerFactory(scheduleConfig); var sched = new StdSchedulerFactory(scheduleConfig).GetScheduler(); if (sched.IsStarted) { // the job is currently running as a RunNow job return; } // create the quartz job and trigger IJobDetail jobDetail = jobService.BuildQuartzJob(job); var jobTrigger = TriggerBuilder.Create() .WithIdentity(job.Guid.ToString(), job.Name) .StartNow() .Build(); // schedule the job sched.ScheduleJob(jobDetail, jobTrigger); // set up the listener to report back from the job when it completes sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs()); // start the scheduler sched.Start(); // Wait 10secs to give job chance to start Thread.Sleep(new TimeSpan(0, 0, 10)); // stop the scheduler when done with job sched.Shutdown(true); } catch (Exception ex) { // create a friendly error message ExceptionLogService.LogException(ex, null); string message = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message); job.LastStatusMessage = message; job.LastStatus = "Error Loading Job"; rockContext.SaveChanges(); } } } }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); ServiceJob job = jobService.Get(JobId); if (job != null) { jobService.RunNow(job, out _); } } }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); ServiceJob job = jobService.Get(JobId); if (job != null) { try { // create a scheduler var scheduleConfig = new System.Collections.Specialized.NameValueCollection(); scheduleConfig.Add("org.quartz.scheduler.instanceName", "RunNow"); var sched = new StdSchedulerFactory(scheduleConfig).GetScheduler(); // create the quartz job and trigger IJobDetail jobDetail = jobService.BuildQuartzJob(job); var jobTrigger = TriggerBuilder.Create() .WithIdentity(job.Guid.ToString(), job.Name) .StartNow() .Build(); // schedule the job sched.ScheduleJob(jobDetail, jobTrigger); // set up the listener to report back from the job when it completes sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs()); // start the scheduler sched.Start(); // Wait 10secs to give job chance to start Thread.Sleep(new TimeSpan(0, 0, 10)); // stop the scheduler when done with job sched.Shutdown(true); } catch (Exception ex) { // create a friendly error message string message = string.Format("Error loading the job: {0}. Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message); job.LastStatusMessage = message; job.LastStatus = "Error Loading Job"; rockContext.SaveChanges(); } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int howMany = dataMap.GetString("HowMany").AsIntegerOrNull() ?? 500000; var commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; bool anyRemaining = UpdateSearchValueRecords(context, howMany, commandTimeout); if (!anyRemaining) { // Verify that there are not any history records that haven't been migrated using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = commandTimeout; var attributeService = new AttributeService(rockContext); var attribute = attributeService.Get("8F528431-A438-4488-8DC3-CA42E66C1B37".AsGuid()); bool valuesExist = attribute != null; if (valuesExist) { valuesExist = new AttributeValueService(rockContext) .Queryable().AsNoTracking() .Where(a => a.AttributeId == attribute.Id) .Any(); } if (!valuesExist) { // Delete the attribute if (attribute != null) { attributeService.Delete(attribute); } // delete job if there are no un-migrated history rows left var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } } }
/// <summary> /// Binds the scheduled jobs. /// </summary> private void BindGrid() { int?scheduledJobId = PageParameter("ScheduledJobId").AsIntegerOrNull(); if (scheduledJobId == null) { return; } var rockContext = new RockContext(); ServiceJobService jobService = new ServiceJobService(rockContext); var job = jobService.Get(scheduledJobId.Value); lJobName.Text = job.Name; var jobHistoryService = new ServiceJobHistoryService(rockContext); SortProperty sortProperty = gScheduledJobHistory.SortProperty; var qry = jobHistoryService.GetServiceJobHistory(scheduledJobId); if (sortProperty != null) { if (sortProperty.Property == "DurationSeconds") { if (sortProperty.Direction == SortDirection.Ascending) { qry = qry.OrderBy(a => System.Data.Entity.DbFunctions.DiffSeconds(a.StopDateTime, a.StartDateTime)); } else { qry = qry.OrderByDescending(a => System.Data.Entity.DbFunctions.DiffSeconds(a.StopDateTime, a.StartDateTime)); } } else { qry = qry.Sort(sortProperty); } } else { qry = qry.OrderByDescending(a => a.StartDateTime); } gScheduledJobHistory.SetLinqDataSource(qry); gScheduledJobHistory.DataBind(); }
/// <summary> /// Executes this instance. /// </summary> /// <param name="message"></param> public override void Execute(Message message) { using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); var job = jobService.Get(message.JobId); if (job == null) { return; } jobService.RunNow(job, out _); } }
/// <summary> /// Deletes the job. /// </summary> /// <param name="jobId">The job identifier.</param> public static void DeleteJob(int jobId) { using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } }
/// <summary> /// Handles the Delete event of the grdScheduledJobs control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gScheduledJobs_Delete(object sender, RowEventArgs e) { ServiceJobService jobService = new ServiceJobService(); ServiceJob job = jobService.Get((int)e.RowKeyValue); string errorMessage; if (!jobService.CanDelete(job, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } jobService.Delete(job, CurrentPersonId); jobService.Save(job, CurrentPersonId); BindGrid(); }
/// <summary> /// Updates the LastStatusMessage of the Rock Job associated with the IJobExecutionContext /// </summary> /// <param name="context">The context.</param> /// <param name="message">The message.</param> public static void UpdateLastStatusMessage(this Quartz.IJobExecutionContext context, string message) { // save the message to context.Result so that RockJobListener will set the save the same message when the Job completes context.Result = message; int jobId = context.GetJobId(); using (var rockContext = new RockContext()) { var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { job.LastStatusMessage = message; rockContext.SaveChanges(); } } }
/// <summary> /// Called by the <see cref="IScheduler"/> when a <see cref="IJobDetail"/> /// is about to be executed (an associated <see cref="ITrigger"/> /// has occurred). /// <para> /// This method will not be invoked if the execution of the Job was vetoed /// by a <see cref="ITriggerListener"/>. /// </para> /// </summary> /// <param name="context"></param> /// <seealso cref="JobExecutionVetoed(IJobExecutionContext)"/> public void JobToBeExecuted(IJobExecutionContext context) { StringBuilder message = new StringBuilder(); // get job type id int jobId = context.JobDetail.Description.AsInteger(); // load job var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null && job.Guid != Rock.SystemGuid.ServiceJob.JOB_PULSE.AsGuid()) { job.LastStatus = "Running"; job.LastStatusMessage = "Started at " + RockDateTime.Now.ToString(); rockContext.SaveChanges(); } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click(object sender, EventArgs e) { ServiceJob job; var rockContext = new RockContext(); ServiceJobService jobService = new ServiceJobService(rockContext); int jobId = int.Parse(hfId.Value); if (jobId == 0) { job = new ServiceJob(); jobService.Add(job); } else { job = jobService.Get(jobId); } job.Name = tbName.Text; job.Description = tbDescription.Text; job.IsActive = cbActive.Checked; job.Class = ddlJobTypes.SelectedValue; job.NotificationEmails = tbNotificationEmails.Text; job.NotificationStatus = (JobNotificationStatus)int.Parse(ddlNotificationStatus.SelectedValue); job.CronExpression = tbCronExpression.Text; if (!job.IsValid) { // Controls will render the error messages return; } RockTransactionScope.WrapTransaction(() => { rockContext.SaveChanges(); job.LoadAttributes(rockContext); Rock.Attribute.Helper.GetEditValues(phAttributes, job); job.SaveAttributeValues(rockContext); }); NavigateToParentPage(); }
public void RemoveTestJob() { if (testJobId == 0) { return; } using (var rockContext = new RockContext()) { var serviceJobService = new ServiceJobService(rockContext); var testJob = serviceJobService.Get(testJobId); if (testJob == null) { return; } serviceJobService.Delete(testJob); rockContext.SaveChanges(); } }
/// <summary> /// Handles the Delete event of the grdScheduledJobs control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gScheduledJobs_Delete(object sender, RowEventArgs e) { var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); ServiceJob job = jobService.Get(e.RowKeyId); string errorMessage; if (!jobService.CanDelete(job, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } jobService.Delete(job); rockContext.SaveChanges(); BindGrid(); }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click(object sender, EventArgs e) { ServiceJob job; ServiceJobService jobService = new ServiceJobService(); int jobId = int.Parse(hfId.Value); if (jobId == 0) { job = new ServiceJob(); jobService.Add(job, CurrentPersonId); } else { job = jobService.Get(jobId); } job.Name = tbName.Text; job.Description = tbDescription.Text; job.IsActive = cbActive.Checked; job.Assembly = tbAssembly.Text; job.Class = tbClass.Text; job.NotificationEmails = tbNotificationEmails.Text; job.NotificationStatus = (JobNotificationStatus)int.Parse(drpNotificationStatus.SelectedValue); job.CronExpression = tbCronExpression.Text; if (!job.IsValid) { // Controls will render the error messages return; } RockTransactionScope.WrapTransaction(() => { jobService.Save(job, CurrentPersonId); }); BindGrid(); pnlDetails.Visible = false; pnlGrid.Visible = true; }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int howMany = dataMap.GetString("HowMany").AsIntegerOrNull() ?? 300000; var commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; CommunicationSchemaUpdates(); bool anyRemaining = UpdateCommunicationRecords(true, howMany, commandTimeout); if (!anyRemaining) { // Verify that there are not any communication records with medium data. using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = commandTimeout; // if there is any v6 MediumDataJson data, it would be have a datalength of 2 or more (blank would be null, '', or '{}') if (!new CommunicationService(rockContext) .Queryable() .Where(c => SqlFunctions.DataLength(c.MediumDataJson) > 2) .Any()) { // delete job if there are no PageView or CommunicationRecipientActivity rows left var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int howMany = dataMap.GetString("HowMany").AsIntegerOrNull() ?? 300000; CommunicationSchemaUpdates(); bool anyRemaining = UpdateCommunicationRecords(true, howMany); if (!anyRemaining) { // Verify that there are not any communication records with medium data. using (var rockContext = new RockContext()) { if (!new CommunicationService(rockContext) .Queryable() .Where(c => c.MediumDataJson != null && c.MediumDataJson != "" && c.MediumDataJson != "{}") .Any()) { // delete job if there are no PageView or CommunicationRecipientActivity rows left var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; CommunicationPendingCommunicationMediumEntityTypeFix(); bool canDeleteJob = true; if (canDeleteJob) { // Verify that there are not any communication records with medium data. using (var rockContext = new RockContext()) { var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; _commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; var deleteJob = dataMap.Get("DeleteJob").ToStringSafe().AsBoolean(); using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = _commandTimeout; _pageViewsTotal = rockContext.Database.SqlQuery <int>("SELECT COUNT(*) FROM PageView").First(); rockContext.Database.ExecuteSqlCommand(@" IF NOT EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_InteractionForeignGuid' AND object_id = OBJECT_ID('Interaction')) BEGIN CREATE UNIQUE NONCLUSTERED INDEX [IX_InteractionForeignGuid] ON [dbo].[Interaction] ([ForeignGuid]) where ForeignGuid is not null END "); _communicationRecipientActivityTotal = rockContext.Database.SqlQuery <int>(@"SELECT COUNT(*) FROM CommunicationRecipientActivity WHERE [Guid] NOT IN ( SELECT ForeignGuid FROM Interaction WHERE ForeignGuid IS NOT NULL ) ").First(); if (_pageViewsTotal == 0 && _communicationRecipientActivityTotal == 0) { // drop the tables rockContext.Database.ExecuteSqlCommand(@" IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'PageView')) BEGIN DROP TABLE PageView; END IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'PageView')) BEGIN DROP TABLE PageView; END IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'PageViewSession')) BEGIN DROP TABLE PageViewSession; END IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'PageViewUserAgent')) BEGIN DROP TABLE PageViewUserAgent; END IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'CommunicationRecipientActivity')) BEGIN DROP TABLE CommunicationRecipientActivity; END "); // delete job if there are no PageView or CommunicationRecipientActivity rows left var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } MigratePageViewsData(context); MigrateCommunicationRecipientActivityData(context); context.UpdateLastStatusMessage($@"Channels Inserted: {_channelsInserted}, Components Inserted: {_componentsInserted}, DeviceTypes Inserted: {_deviceTypesInserted}, Sessions Inserted: {_sessionsInserted}, PageViews Moved: {_pageViewsMoved}/{_pageViewsTotal}, CommunicationRecipientActivity Moved: {_communicationRecipientActivityMoved}/{_communicationRecipientActivityTotal} "); }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); InteractionChannelService channelService = new InteractionChannelService(rockContext); InteractionComponentService componentService = new InteractionComponentService(rockContext); InteractionService interactionService = new InteractionService(rockContext); ScheduleService scheduleService = new ScheduleService(rockContext); LocationService locationService = new LocationService(rockContext); AttendanceService attendanceService = new AttendanceService(rockContext); GroupService groupService = new GroupService(rockContext); // Load the channel InteractionChannelCache channel = InteractionChannelCache.Read(dataMap.GetString("InteractionChannel").AsGuid()); // Setup int campusLocationTypeId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_CAMPUS).Id; var groupType = GroupTypeCache.Read(dataMap.GetString("GroupType").AsGuid()); var groups = groupService.GetByGroupTypeId(groupType.Id); string operation = !string.IsNullOrWhiteSpace(dataMap.GetString("Operation")) ? dataMap.GetString("Operation") : null; // Fetch the job so we can get the last run date/time int jobId = Convert.ToInt16(context.JobDetail.Description); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); DateTime lastRun = job?.LastSuccessfulRunDateTime ?? DateTime.MinValue; var componentCampusMapping = dataMap.GetString("ComponentCampusMapping").AsDictionaryOrNull(); foreach (var componentName in componentCampusMapping.Keys) { var component = componentService.Queryable().Where(cs => cs.Name.ToLower() == componentName.ToLower() && cs.ChannelId == channel.Id).FirstOrDefault(); CampusCache campus = CampusCache.All().Where(c => c.Name == componentCampusMapping[componentName]).FirstOrDefault(); if (campus != null && component != null) { Group group = groups.Where(g => g.IsActive == true && g.CampusId == campus.Id).FirstOrDefault(); if (group?.GroupLocations != null) { foreach (var gl in group?.GroupLocations) { Location location = gl.Location; foreach (Schedule schedule in gl.Schedules) { var occurrences = schedule.GetOccurrences(DateTime.MinValue, DateTime.Now); foreach (var occurrence in occurrences) { DateTime startDate = occurrence.Period.StartTime.Value; DateTime endDate = occurrence.Period.EndTime.Value; var peopleAttended = interactionService.Queryable().Where( i => i.InteractionComponentId == component.Id && i.InteractionDateTime <= endDate && i.InteractionEndDateTime >= startDate && i.PersonAliasId != null && (i.CreatedDateTime > lastRun || i.PersonalDevice.ModifiedDateTime > lastRun || i.PersonalDevice.CreatedDateTime > lastRun) && (operation == null || i.Operation == operation) ).Select(i => i.PersonAliasId).Distinct(); int newAttendance = 0; foreach (int personAliasId in peopleAttended) { // Make sure we don't already have an attendance Record if (!attendanceService.Queryable().Any(a => DbFunctions.TruncateTime(a.StartDateTime) == occurrence.Period.StartTime.Value.Date && a.ScheduleId == schedule.Id && a.PersonAliasId == personAliasId && a.GroupId == group.Id && a.LocationId == location.Id && a.DidAttend == true)) { Attendance attendance = new Attendance() { PersonAliasId = personAliasId, CampusId = campus.Id, GroupId = group.Id, LocationId = location.Id, ScheduleId = schedule.Id, StartDateTime = occurrence.Period.StartTime.Value, EndDateTime = occurrence.Period?.EndTime?.Value, DidAttend = true }; attendanceService.Add(attendance); newAttendance++; } } if (newAttendance > 0) { rockContext.SaveChanges(); context.Result += string.Format("{0} people attended {1} on {2} (Component {3}).\n", newAttendance, campus.Name, occurrence.Period.StartTime.Value.ToString("MM/dd/yyyy h:mm tt"), component.Name); } } } } } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> /// <exception cref="System.NotImplementedException"></exception> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; _commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; using (var rockContext = new RockContext()) { rockContext.Database.CommandTimeout = _commandTimeout; _remainingAttendanceRecords = rockContext.Database.SqlQuery <int>($@" SELECT COUNT(*) FROM [Attendance] WHERE [OccurrenceId] = 1 ").First(); if (_remainingAttendanceRecords == 0) { // drop the indexes and columns rockContext.Database.ExecuteSqlCommand(@" IF NOT EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_OccurrenceId' AND object_id = OBJECT_ID('Attendance')) BEGIN CREATE INDEX [IX_OccurrenceId] ON [dbo].[Attendance]([OccurrenceId]) END IF EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_GroupId' AND object_id = OBJECT_ID('Attendance')) BEGIN DROP INDEX [IX_GroupId] ON [dbo].[Attendance] END IF EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_GroupId_StartDateTime_DidAttend' AND object_id = OBJECT_ID('Attendance')) BEGIN DROP INDEX [IX_GroupId_StartDateTime_DidAttend] ON [dbo].[Attendance] END IF EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_PersonAliasId' AND object_id = OBJECT_ID('Attendance')) BEGIN DROP INDEX [IX_PersonAliasId] ON [dbo].[Attendance] END IF EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_StartDateTime_DidAttend' AND object_id = OBJECT_ID('Attendance')) BEGIN DROP INDEX [IX_StartDateTime_DidAttend] ON [dbo].[Attendance] END IF EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_SundayDate' AND object_id = OBJECT_ID('Attendance')) BEGIN DROP INDEX [IX_SundayDate] ON [dbo].[Attendance] END IF NOT EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_PersonAliasId' AND object_id = OBJECT_ID('Attendance')) BEGIN CREATE NONCLUSTERED INDEX [IX_PersonAliasId] ON [dbo].[Attendance] ( [PersonAliasId] ASC ) INCLUDE ( [Id], [StartDateTime], [DidAttend], [CampusId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] END IF NOT EXISTS(SELECT * FROM sys.indexes WHERE name = 'IX_StartDateTime_DidAttend' AND object_id = OBJECT_ID('Attendance')) BEGIN CREATE NONCLUSTERED INDEX [IX_StartDateTime_DidAttend] ON [dbo].[Attendance] ( [StartDateTime] ASC, [DidAttend] ASC ) INCLUDE ( [Id], [CampusId], [PersonAliasId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] END ALTER TABLE [dbo].[Attendance] DROP CONSTRAINT [FK_dbo.Attendance_dbo.Group_GroupId], [FK_dbo.Attendance_dbo.Location_LocationId], [FK_dbo.Attendance_dbo.Schedule_ScheduleId] ALTER TABLE [dbo].[Attendance] DROP COLUMN [LocationId], [ScheduleId], [GroupId], [DidNotOccur], [SundayDate] IF NOT EXISTS ( SELECT [Id] FROM [Attendance] WHERE [OccurrenceId] = 1 ) BEGIN DELETE [AttendanceOccurrence] WHERE [Id] = 1 END "); // delete job if there are no unlined attendance records var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { jobService.Delete(job); rockContext.SaveChanges(); return; } } } MigrateAttendanceData(context); context.UpdateLastStatusMessage($@"Attendance Records Read: {_attendanceRecordsUpdated}, Occurrence Records Inserted: { _occurrenceRecordsAdded}, Attendance Records Updated: { _attendanceRecordsUpdated} "); }
public virtual void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); var groupService = new GroupService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var connectionRequestService = new ConnectionRequestService(rockContext); var group = groupService.GetByGuid(dataMap.GetString("ConnectionGroup").AsGuid()); var systemEmail = dataMap.GetString("SystemEmail").AsGuidOrNull(); if (!systemEmail.HasValue) { throw new Exception("System Email is required!"); } List <int> connectorPersonAliasIds = new List <int>(); var recipients = new List <RecipientData>(); if (group != null) { var childrenGroups = groupService.GetAllDescendents(group.Id); var allGroups = childrenGroups.ToList(); allGroups.Add(group); connectorPersonAliasIds = allGroups.SelectMany(p => p.Members.Select(m => m.Person).SelectMany(psn => psn.Aliases).Select(a => a.Id)).ToList(); } var connectionOpportunities = dataMap.GetString("ConnectionOpportunities").SplitDelimitedValues(); // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); DateTime _midnightToday = RockDateTime.Today.AddDays(1); var currentDateTime = RockDateTime.Now; PersonService personService = new PersonService(rockContext); var connectionRequestsQry = connectionRequestService.Queryable().Where(cr => connectionOpportunities.Contains(cr.ConnectionOpportunity.Guid.ToString()) && cr.ConnectorPersonAliasId != null && ( cr.ConnectionState == ConnectionState.Active || (cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < _midnightToday) )); // If we have a group of connectors, limit it to them. if (group != null) { List <int> groupconnectorPersonIds = group.ActiveMembers().SelectMany(gm => gm.Person.Aliases).Select(a => a.Id).ToList(); connectionRequestsQry = connectionRequestsQry.Where(cr => cr.ConnectorPersonAliasId.HasValue && groupconnectorPersonIds.Contains(cr.ConnectorPersonAliasId.Value)); } // Now get all the connection data for everyone. var connectionRequestGroups = connectionRequestsQry.GroupBy(cr => cr.ConnectorPersonAlias.PersonId); foreach (var connectionRequestGroup in connectionRequestGroups) { Person person = personService.Get(connectionRequestGroup.Key); List <ConnectionOpportunity> opportunities = connectionRequestGroup.Select(a => a.ConnectionOpportunity).Distinct().ToList(); var newConnectionRequests = connectionRequestGroup.Where(cr => cr.CreatedDateTime >= job.LastSuccessfulRunDateTime).GroupBy(cr => cr.ConnectionOpportunityId).ToList(); // Get all the idle connections var idleConnectionRequests = connectionRequestGroup .Where(cr => ( (cr.ConnectionRequestActivities.Any() && cr.ConnectionRequestActivities.Max(ra => ra.CreatedDateTime) < currentDateTime.AddDays(-cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle))) || (!cr.ConnectionRequestActivities.Any() && cr.CreatedDateTime < currentDateTime.AddDays(-cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle)) ) .Select(a => new { ConnectionOpportunityId = a.ConnectionOpportunityId, Id = a.Id }) .GroupBy(cr => cr.ConnectionOpportunityId).ToList(); // get list of requests that have a status that is considered critical. var criticalConnectionRequests = connectionRequestGroup .Where(r => r.ConnectionStatus.IsCritical ) .Select(a => new { ConnectionOpportunityId = a.ConnectionOpportunityId, Id = a.Id }) .GroupBy(cr => cr.ConnectionOpportunityId).ToList(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Requests", connectionRequestGroup.Select(c => c).ToList()); mergeFields.Add("ConnectionOpportunities", opportunities); mergeFields.Add("ConnectionRequests", connectionRequestGroup.GroupBy(cr => cr.ConnectionOpportunity).ToList()); mergeFields.Add("NewConnectionRequests", newConnectionRequests); mergeFields.Add("IdleConnectionRequestIds", idleConnectionRequests); mergeFields.Add("CriticalConnectionRequestIds", criticalConnectionRequests); mergeFields.Add("Person", person); mergeFields.Add("LastRunDate", job.LastSuccessfulRunDateTime); mergeFields.Add("IncludeOpportunityBreakdown", dataMap.GetString("IncludeOpportunityBreakdown").AsBoolean()); mergeFields.Add("IncludeAllRequests", dataMap.GetString("IncludeAllRequests").AsBoolean()); recipients.Add(new RecipientData(person.Email, mergeFields)); } // If we have valid recipients, send the email if (recipients.Count > 0) { RockEmailMessage email = new RockEmailMessage(systemEmail.Value); email.SetRecipients(recipients); email.CreateCommunicationRecord = dataMap.GetString("SaveCommunicationHistory").AsBoolean(); email.Send(); } context.Result = string.Format("{0} Connection reminders sent", recipients.Count); }
/// <summary> /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/> /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called. /// </summary> /// <param name="context"></param> /// <param name="jobException"></param> public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) { StringBuilder message = new StringBuilder(); bool sendMessage = false; // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); // load job var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); // format the message message.Append(string.Format("The job {0} ran for {1} seconds on {2}. Below is the results:<p>", job.Name, context.JobRunTime.TotalSeconds, context.FireTimeUtc.Value.DateTime.ToLocalTime())); // if noticiation staus is all set flag to send message if (job.NotificationStatus == JobNotificationStatus.All) { sendMessage = true; } // set last run date job.LastRunDateTime = RockDateTime.Now; // context.FireTimeUtc.Value.DateTime.ToLocalTime(); // set run time job.LastRunDurationSeconds = Convert.ToInt32(context.JobRunTime.TotalSeconds); // set the scheduler name job.LastRunSchedulerName = context.Scheduler.SchedulerName; // determine if an error occured if (jobException == null) { job.LastSuccessfulRunDateTime = job.LastRunDateTime; job.LastStatus = "Success"; if (context.Result is string) { job.LastStatusMessage = context.Result as string; } message.Append("Result: Success"); // determine if message should be sent if (job.NotificationStatus == JobNotificationStatus.Success) { sendMessage = true; } } else { Exception exceptionToLog = jobException; // drill down to the interesting exception while (exceptionToLog is Quartz.SchedulerException && exceptionToLog.InnerException != null) { exceptionToLog = exceptionToLog.InnerException; } // log the exception to the database ExceptionLogService.LogException(exceptionToLog, null); var summaryException = exceptionToLog; // put the exception into the status job.LastStatus = "Exception"; AggregateException aggregateException = summaryException as AggregateException; if (aggregateException != null && aggregateException.InnerExceptions != null && aggregateException.InnerExceptions.Count == 1) { // if it's an aggregate, but there is only one, convert it to a single exception summaryException = aggregateException.InnerExceptions[0]; aggregateException = null; } if (aggregateException != null) { var firstException = aggregateException.InnerExceptions.First(); job.LastStatusMessage = "One or more exceptions occurred. First Exception: " + firstException.Message; summaryException = firstException; } else { job.LastStatusMessage = summaryException.Message; } message.Append("Result: Exception<p>Message:<br>" + job.LastStatusMessage); if (summaryException.InnerException != null) { job.LastStatusMessage += " (" + summaryException.InnerException.Message + ")"; message.Append("<p>Inner Exception:<br>" + summaryException.InnerException.Message); } if (job.NotificationStatus == JobNotificationStatus.Error) { sendMessage = true; } } rockContext.SaveChanges(); // send notification if (sendMessage) { // TODO: implement email send once it's available } }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); var commandTimeout = dataMap.GetString("CommandTimeout").AsIntegerOrNull() ?? 3600; rockContext.Database.CommandTimeout = commandTimeout; AttributeValueService attributeValueService = new AttributeValueService(rockContext); PersonService personService = new PersonService(rockContext); var personAliasQry = new PersonAliasService(rockContext).Queryable(); var familyGroupMemberQry = new GroupMemberService(rockContext).Queryable().Where(gm => gm.Group.GroupTypeId == 10); var groupQry = new GroupService(rockContext).Queryable().Where(g => g.GroupTypeId == 10); var attendanceQry = new AttendanceService(rockContext).Queryable().Where(a => a.DidAttend == true); var currentlyEraAttribue = AttributeCache.Get("CE5739C5-2156-E2AB-48E5-1337C38B935E"); var firstAttendanceAttribute = AttributeCache.Get("8F404727-82A5-4855-9714-62DFAB834BB2"); var eraStartDateAttribute = AttributeCache.Get("A106610C-A7A1-469E-4097-9DE6400FDFC2"); var attendanceVerificationMethod = AttributeCache.Get("7244EF82-FD1E-4B00-B2A1-114A79F09555"); var attendanceVerifiedType = AttributeCache.Get("64C05D55-1697-4773-AE14-5C9596B71FF4"); var historyCategory = CategoryCache.Get(Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES); var personEntityType = EntityTypeCache.Get(typeof(Rock.Model.Person)); var attributeEntityType = EntityTypeCache.Get(typeof(Rock.Model.Attribute)); var inEraQry = attributeValueService.Queryable() .Where(av => av.AttributeId == currentlyEraAttribue.Id && av.Value == "True") .Select(av => av.EntityId); var firstAttQry = attributeValueService.Queryable() .Where(av => av.AttributeId == firstAttendanceAttribute.Id && av.Value != null && av.Value != "") .Select(av => av.EntityId); var eraStartQry = attributeValueService.Queryable() .Where(av => av.AttributeId == eraStartDateAttribute.Id); var take = dataMap.GetString("Take").AsIntegerOrNull() ?? 1000; //Linq! var people = personService.Queryable() //Get all the people .Where(p => inEraQry.Contains(p.Id)) //Who are era .Where(p => !firstAttQry.Contains(p.Id)) //And don't have a first attendance .Take(take) .Join( //Get the ERA Start Date eraStartQry, p => p.Id, a => a.EntityId, (p, a) => new { Person = p, EraStartDate = a.Value }) .GroupJoin( //Get group membership for all family groups familyGroupMemberQry, o => o.Person.Id, gm => gm.PersonId, (o, gm) => new { o.Person, o.EraStartDate, FirstAttendance = gm.Select(gm2 => gm2.Group).SelectMany(g => g.Members.Select(gm3 => gm3.Person)) //Get all family members .GroupJoin( personAliasQry, //Get all person alias ids for all family members p => p.Id, pa => pa.PersonId, (p, pa) => pa.GroupJoin( attendanceQry, //Get all attendance records for all family members pa2 => pa2.Id, a => a.PersonAliasId, (pa2, a) => a) .SelectMany(a => a)) //Compact .SelectMany(a => a) //Compact .OrderBy(a2 => a2.StartDateTime) //Sort .FirstOrDefault() //Get first }) .ToList(); var counter = 0; foreach (var person in people) { try { //Before we continue. We need to remove any existing attribute values. var removeQry = string.Format(@"delete from AttributeValue where EntityId = {0} and AttributeId in ({1},{2},{3})", person.Person.Id, firstAttendanceAttribute.Id, attendanceVerificationMethod.Id, attendanceVerifiedType.Id); rockContext.Database.ExecuteSqlCommand(removeQry); //Lets add in the attribute values! if (person.FirstAttendance != null) { var methodAV = new AttributeValue { IsSystem = false, AttributeId = attendanceVerificationMethod.Id, EntityId = person.Person.Id, Value = "Automatic" }; var methodHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = attendanceVerificationMethod.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance Verification Method", NewValue = "Automatic" }; var attendanceTypeAV = new AttributeValue { IsSystem = false, AttributeId = attendanceVerifiedType.Id, EntityId = person.Person.Id, Value = "SECC Attendance" }; var attendanceTypeHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = attendanceVerifiedType.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance Verification Type", NewValue = "SECC Attendance" }; var firstAttendanceAV = new AttributeValue { IsSystem = false, AttributeId = firstAttendanceAttribute.Id, EntityId = person.Person.Id, Value = person.FirstAttendance.StartDateTime.Date.ToString("MM/dd/yyyy") }; var firstAttendanceHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = firstAttendanceAttribute.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance 1st Verified Date", NewValue = person.FirstAttendance.StartDateTime.Date.ToString("MM/dd/yyyy") }; rockContext.BulkInsert(new List <AttributeValue> { methodAV, attendanceTypeAV, firstAttendanceAV }); rockContext.BulkInsert(new List <History> { methodHistory, attendanceTypeHistory, firstAttendanceHistory }); } else { var methodAV = new AttributeValue { IsSystem = false, AttributeId = attendanceVerificationMethod.Id, EntityId = person.Person.Id, Value = "Automatic" }; var methodHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = attendanceVerificationMethod.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance Verification Method", NewValue = "Automatic" }; var attendanceTypeAV = new AttributeValue { IsSystem = false, AttributeId = attendanceVerifiedType.Id, EntityId = person.Person.Id, Value = "eRA Start Date" }; var attendanceTypeHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = attendanceVerifiedType.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance Verification Type", NewValue = "eRA Start Date" }; var firstAttendanceAV = new AttributeValue { IsSystem = false, AttributeId = firstAttendanceAttribute.Id, EntityId = person.Person.Id, Value = person.EraStartDate.AsDateTime().Value.Date.ToString("MM/dd/yyyy") }; var firstAttendanceHistory = new History { IsSystem = false, CategoryId = historyCategory.Id, EntityTypeId = personEntityType.Id, EntityId = person.Person.Id, RelatedEntityTypeId = attributeEntityType.Id, RelatedEntityId = firstAttendanceAttribute.Id, Verb = "MODIFY", ChangeType = "Property", ValueName = "Attendance 1st Verified Date", NewValue = person.EraStartDate.AsDateTime().Value.Date.ToString("MM/dd/yyyy") }; rockContext.BulkInsert(new List <AttributeValue> { methodAV, attendanceTypeAV, firstAttendanceAV }); rockContext.BulkInsert(new List <History> { methodHistory, attendanceTypeHistory, firstAttendanceHistory }); } counter++; } catch (Exception e) { var ex = string.Format("Could not set first Attendance data for {0} - {1}", person.Person.FullName, person.Person.Id); ExceptionLogService.LogException(new Exception(ex, e)); } if (counter % 100 == 0) { var jobId = context.GetJobId(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job != null) { job.LastStatusMessage = string.Format("Updated {0} People of {1}", counter, people.Count); rockContext.SaveChanges(false); } } } }
/// <summary> /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/> /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called. /// </summary> /// <param name="context"></param> /// <param name="jobException"></param> public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) { bool sendMessage = false; // get job id int jobId = context.GetJobId(); // load job var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); if (job == null) { // if job was deleted or wasn't found, just exit return; } // if notification status is all set flag to send message if (job.NotificationStatus == JobNotificationStatus.All) { sendMessage = true; } // set last run date job.LastRunDateTime = RockDateTime.Now; // context.FireTimeUtc.Value.DateTime.ToLocalTime(); // set run time job.LastRunDurationSeconds = Convert.ToInt32(context.JobRunTime.TotalSeconds); // set the scheduler name job.LastRunSchedulerName = context.Scheduler.SchedulerName; // determine if an error occurred if (jobException == null) { job.LastSuccessfulRunDateTime = job.LastRunDateTime; job.LastStatus = "Success"; if (context.Result is string) { job.LastStatusMessage = context.Result as string; } else { job.LastStatusMessage = string.Empty; } // determine if message should be sent if (job.NotificationStatus == JobNotificationStatus.Success) { sendMessage = true; } } else { Exception exceptionToLog = jobException; // drill down to the interesting exception while (exceptionToLog is Quartz.SchedulerException && exceptionToLog.InnerException != null) { exceptionToLog = exceptionToLog.InnerException; } // log the exception to the database ExceptionLogService.LogException(exceptionToLog, null); var summaryException = exceptionToLog; // put the exception into the status job.LastStatus = "Exception"; AggregateException aggregateException = summaryException as AggregateException; if (aggregateException != null && aggregateException.InnerExceptions != null && aggregateException.InnerExceptions.Count == 1) { // if it's an aggregate, but there is only one, convert it to a single exception summaryException = aggregateException.InnerExceptions[0]; aggregateException = null; } if (aggregateException != null) { var firstException = aggregateException.InnerExceptions.First(); job.LastStatusMessage = "One or more exceptions occurred. First Exception: " + firstException.Message; summaryException = firstException; } else { job.LastStatusMessage = summaryException.Message; } if (job.NotificationStatus == JobNotificationStatus.Error) { sendMessage = true; } } rockContext.SaveChanges(); // Add job history AddServiceJobHistory(job, rockContext); // send notification if (sendMessage) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null, new Lava.CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); mergeFields.Add("Job", job); try { if (jobException != null) { mergeFields.Add("Exception", Hash.FromAnonymousObject(jobException)); } } catch { // ignore } var notificationEmailAddresses = job.NotificationEmails.ResolveMergeFields(mergeFields).SplitDelimitedValues().ToList(); var emailMessage = new RockEmailMessage(Rock.SystemGuid.SystemEmail.CONFIG_JOB_NOTIFICATION.AsGuid()); emailMessage.AdditionalMergeFields = mergeFields; // NOTE: the EmailTemplate may also have TO: defined, so even if there are no notificationEmailAddress defined for this specific job, we still should send the mail foreach (var notificationEmailAddress in notificationEmailAddresses) { emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(notificationEmailAddress, null)); } emailMessage.Send(); } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click(object sender, EventArgs e) { try { ExpressionDescriptor.GetDescription(tbCronExpression.Text); } catch (Exception ex) { tbCronExpression.ShowErrorMessage("Invalid Cron Expression: " + ex.Message); return; } ServiceJob job; var rockContext = new RockContext(); ServiceJobService jobService = new ServiceJobService(rockContext); int jobId = int.Parse(hfId.Value); if (jobId == 0) { job = new ServiceJob(); jobService.Add(job); } else { job = jobService.Get(jobId); } job.Name = tbName.Text; job.Description = tbDescription.Text; job.IsActive = cbActive.Checked; if (job.Class != ddlJobTypes.SelectedValue) { job.Class = ddlJobTypes.SelectedValue; //// if the Class has changed, the current Assembly value might not match, //// so set the Assembly to null to have Rock figure it out automatically job.Assembly = null; } job.NotificationEmails = tbNotificationEmails.Text; job.NotificationStatus = (JobNotificationStatus)int.Parse(ddlNotificationStatus.SelectedValue); job.CronExpression = tbCronExpression.Text; if (!job.IsValid) { // Controls will render the error messages return; } rockContext.WrapTransaction(() => { rockContext.SaveChanges(); job.LoadAttributes(rockContext); Rock.Attribute.Helper.GetEditValues(phAttributes, job); job.SaveAttributeValues(rockContext); }); NavigateToParentPage(); }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); InteractionChannelService channelService = new InteractionChannelService(rockContext); InteractionComponentService componentService = new InteractionComponentService(rockContext); InteractionService interactionService = new InteractionService(rockContext); ScheduleService scheduleService = new ScheduleService(rockContext); LocationService locationService = new LocationService(rockContext); AttendanceService attendanceService = new AttendanceService(rockContext); AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext); GroupService groupService = new GroupService(rockContext); // Load the channel InteractionChannelCache channel = InteractionChannelCache.Get(dataMap.GetString("InteractionChannel").AsGuid()); // Setup int campusLocationTypeId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_CAMPUS).Id; var groupType = GroupTypeCache.Get(dataMap.GetString("GroupType").AsGuid()); var groupLocations = groupService.GetByGroupTypeId(groupType.Id).Where(g => g.IsActive == true).SelectMany(g => g.GroupLocations).ToList(); string operation = !string.IsNullOrWhiteSpace(dataMap.GetString("Operation")) ? dataMap.GetString("Operation") : null; // Fetch the job so we can get the last run date/time int jobId = Convert.ToInt16(context.JobDetail.Description); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); DateTime lastRun = job?.LastSuccessfulRunDateTime ?? DateTime.MinValue; var componentCampusMapping = dataMap.GetString("ComponentCampusMapping").AsDictionaryOrNull(); DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||"); // Flip the component campus mapping around and translate to ids Dictionary <int, List <int> > campusComponentIds = new Dictionary <int, List <int> >(); foreach (CampusCache campus in CampusCache.All()) { var componentNames = componentCampusMapping.Where(ccm => ccm.Value == campus.Name).Select(c => c.Key.ToLower()); campusComponentIds[campus.Id] = componentService.Queryable().Where(cs => componentNames.Contains(cs.Name.ToLower()) && cs.ChannelId == channel.Id).Select(c => c.Id).ToList(); } foreach (GroupLocation gl in groupLocations) { if (gl.Group.CampusId.HasValue) { Location location = gl.Location; List <int> componentIds = campusComponentIds[gl.Group.CampusId.Value]; foreach (Schedule schedule in gl.Schedules) { var occurrences = schedule.GetOccurrences(dateRange.Start.Value, dateRange.End.Value); foreach (var occurrence in occurrences) { DateTime startDate = occurrence.Period.StartTime.Value; DateTime endDate = occurrence.Period.EndTime.Value; var peopleAttended = interactionService.Queryable().Where( i => componentIds.Contains(i.InteractionComponentId) && i.InteractionDateTime <= endDate && i.InteractionEndDateTime >= startDate && i.PersonAliasId != null && (i.CreatedDateTime > lastRun || i.PersonalDevice.ModifiedDateTime > lastRun || i.PersonalDevice.CreatedDateTime > lastRun) && (operation == null || i.Operation == operation) ).Select(i => i.PersonAliasId).Distinct(); int newAttendance = 0; var occurrenceModel = attendanceOccurrenceService.Get(occurrence.Period.StartTime.Value.Date, gl.GroupId, location.Id, schedule.Id); // Make sure we don't already have an attendance Record var existingAttendees = attendanceOccurrenceService.Queryable().Where(ao => DbFunctions.TruncateTime(ao.OccurrenceDate) == occurrence.Period.StartTime.Value.Date && ao.ScheduleId == schedule.Id && ao.GroupId == gl.GroupId && ao.LocationId == location.Id).SelectMany(a => a.Attendees).Where(a => a.DidAttend == true).Select(a => a.PersonAliasId); foreach (int personAliasId in peopleAttended.Except(existingAttendees)) { // Check to see if an occurrence exists already if (occurrenceModel == null) { var attendance = attendanceService.AddOrUpdate(personAliasId, occurrence.Period.StartTime.Value, gl.GroupId, location.Id, schedule.Id, gl.Group.CampusId); attendance.EndDateTime = occurrence.Period?.EndTime?.Value; attendance.DidAttend = true; attendance.CampusId = gl.Group.CampusId; occurrenceModel = attendance.Occurrence; } else { Attendance attendance = new Attendance(); attendance.PersonAliasId = personAliasId; attendance.OccurrenceId = occurrenceModel.Id; attendance.StartDateTime = occurrence.Period.StartTime.Value; attendance.EndDateTime = occurrence.Period?.EndTime?.Value; attendance.DidAttend = true; attendance.CampusId = gl.Group.CampusId; attendanceService.Add(attendance); } newAttendance++; } if (newAttendance > 0) { rockContext.SaveChanges(); context.Result += string.Format("{0} people attended {1} on {2}.\n", newAttendance, gl.Group.Campus.Name, occurrence.Period.StartTime.Value.ToString("MM/dd/yyyy h:mm tt")); } } } } } }
/// <summary> /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/> /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called. /// </summary> /// <param name="context"></param> /// <param name="jobException"></param> public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) { StringBuilder message = new StringBuilder(); bool sendMessage = false; // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); // load job ServiceJobService jobService = new ServiceJobService(); ServiceJob job = jobService.Get(jobId); // format the message message.Append(String.Format("The job {0} ran for {1} seconds on {2}. Below is the results:<p>", job.Name, context.JobRunTime.TotalSeconds, context.FireTimeUtc.Value.DateTime.ToLocalTime())); // if noticiation staus is all set flag to send message if (job.NotificationStatus == JobNotificationStatus.All) { sendMessage = true; } // set last run date job.LastRunDateTime = context.FireTimeUtc.Value.DateTime.ToLocalTime(); // set run time job.LastRunDurationSeconds = Convert.ToInt32(context.JobRunTime.TotalSeconds); // set the scheduler name job.LastRunSchedulerName = context.Scheduler.SchedulerName; // determine if an error occured if (jobException == null) { job.LastSuccessfulRunDateTime = job.LastRunDateTime; job.LastStatus = "Success"; job.LastStatusMessage = ""; message.Append("Result: Success"); // determine if message should be sent if (job.NotificationStatus == JobNotificationStatus.Success) { sendMessage = true; } } else { // put the exception into the status job.LastStatus = "Exception"; job.LastStatusMessage = jobException.Message; message.Append("Result: Exception<p>Message:<br>" + jobException.Message); if (jobException.InnerException != null) { job.LastStatusMessage += " Inner Exception: " + jobException.InnerException.Message; message.Append("<p>Inner Exception:<br>" + jobException.InnerException.Message); } if (job.NotificationStatus == JobNotificationStatus.Error) { sendMessage = true; } } jobService.Save(job, null); // send notification if (sendMessage) { // TODO: implement email send once it's available } }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); var connectionOpportunities = dataMap.GetString("ConnectionOpportunities").SplitDelimitedValues(); var systemEmail = dataMap.GetString("Email").AsGuidOrNull(); if (!systemEmail.HasValue) { throw new Exception("System Email is required!"); } // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); var jobService = new ServiceJobService(rockContext); var job = jobService.Get(jobId); DateTime _midnightToday = RockDateTime.Today.AddDays(1); var currentDateTime = RockDateTime.Now; var recipients = new List <RockEmailMessageRecipient>(); ConnectionRequestService connectionRequestService = new ConnectionRequestService(rockContext); PersonService personService = new PersonService(rockContext); var connectionRequestsQry = connectionRequestService.Queryable().Where(cr => connectionOpportunities.Contains(cr.ConnectionOpportunity.Guid.ToString()) && cr.ConnectorPersonAliasId != null && ( cr.ConnectionState == ConnectionState.Active || (cr.ConnectionState == ConnectionState.FutureFollowUp && cr.FollowupDate.HasValue && cr.FollowupDate.Value < _midnightToday) )); var connectionRequestGroups = connectionRequestsQry.GroupBy(cr => cr.ConnectorPersonAlias.PersonId); foreach (var group in connectionRequestGroups) { Person person = personService.Get(group.Key); List <ConnectionOpportunity> opportunities = group.Select(a => a.ConnectionOpportunity).Distinct().ToList(); var newConnectionRequests = group.Where(cr => cr.CreatedDateTime >= job.LastRunDateTime).GroupBy(cr => cr.ConnectionOpportunityId).ToList(); // Get all the idle connections var idleConnectionRequests = group .Where(cr => ( (cr.ConnectionRequestActivities.Any() && cr.ConnectionRequestActivities.Max(ra => ra.CreatedDateTime) < currentDateTime.AddDays(-cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle))) || (!cr.ConnectionRequestActivities.Any() && cr.CreatedDateTime < currentDateTime.AddDays(-cr.ConnectionOpportunity.ConnectionType.DaysUntilRequestIdle)) ) .Select(a => new { ConnectionOpportunityId = a.ConnectionOpportunityId, Id = a.Id }) .GroupBy(cr => cr.ConnectionOpportunityId).ToList(); // get list of requests that have a status that is considered critical. var criticalConnectionRequests = group .Where(r => r.ConnectionStatus.IsCritical ) .Select(a => new { ConnectionOpportunityId = a.ConnectionOpportunityId, Id = a.Id }) .GroupBy(cr => cr.ConnectionOpportunityId).ToList(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("ConnectionOpportunities", opportunities); mergeFields.Add("ConnectionRequests", group.GroupBy(cr => cr.ConnectionOpportunity).ToList()); mergeFields.Add("NewConnectionRequests", newConnectionRequests); mergeFields.Add("IdleConnectionRequestIds", idleConnectionRequests); mergeFields.Add("CriticalConnectionRequestIds", criticalConnectionRequests); mergeFields.Add("Person", person); mergeFields.Add("LastRunDate", job.LastRunDateTime); recipients.Add(new RockEmailMessageRecipient(person, mergeFields)); } var emailMessage = new RockEmailMessage(systemEmail.Value); emailMessage.SetRecipients(recipients); emailMessage.CreateCommunicationRecord = dataMap.GetString("SaveCommunicationHistory").AsBoolean(); emailMessage.Send(); context.Result = string.Format("Sent " + recipients.Count + " connection digest emails."); }