/// <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;
                        }
                    }
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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();
                    }
                }
            }
        }
示例#4
0
        /// <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 _);
                }
            }
        }
示例#5
0
        /// <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;
                        }
                    }
                }
            }
        }
示例#7
0
        /// <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();
        }
示例#8
0
        /// <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 _);
            }
        }
示例#9
0
        /// <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;
                }
            }
        }
示例#10
0
        /// <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();
        }
示例#11
0
        /// <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();
                }
            }
        }
示例#12
0
        /// <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();
        }
示例#14
0
        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();
        }
示例#16
0
        /// <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;
                        }
                    }
                }
            }
        }
示例#19
0
        /// <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;
                    }
                }
            }
        }
示例#20
0
        /// <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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#22
0
        /// <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}
");
        }
示例#23
0
        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);
        }
示例#24
0
        /// <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
            }
        }
示例#25
0
        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);
                    }
                }
            }
        }
示例#26
0
        /// <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"));
                            }
                        }
                    }
                }
            }
        }
示例#29
0
        /// <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.");
        }