/// <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;
                        }
                    }
                }
            }
        }
        /// <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;
                        }
                    }
                }
            }
        }
Beispiel #3
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;
                }
            }
        }
Beispiel #4
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();
        }
Beispiel #5
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();
        }
        /// <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;
                        }
                    }
                }
            }
        }
Beispiel #9
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;
                    }
                }
            }
        }
Beispiel #10
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}
");
        }
Beispiel #11
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}
");
        }
Beispiel #12
0
        void IJob.Execute(IJobExecutionContext context)
        {
            // Get the current password
            string currentEncryptionPassword = RockCrypto.GetConfiguredEncryptionPassword();

            byte[] currentEncryptionKey = RockCrypto.GetDerivedKey(currentEncryptionPassword);

            // Generate a new password
            string newEncryptionPassword = RockCrypto.GenerateRandomBase64String(128);

            byte[] newEncryptionKey = RockCrypto.GetDerivedKey(newEncryptionPassword);

            context.UpdateLastStatusMessage("Migrating Attribute DefaultValues");

            // Re-encrypt all Attribute DefaultValues

            using (RockContext rockContext = new RockContext())
            {
                // Make a new Attribute service
                AttributeService attributeService = new AttributeService(rockContext);

                // Get all attributes that have an encrypted DefaultValue
                // Normally we just use the field type to define what's encrypted or not, but System
                // Settings don't have a field type so we have to do a bit of extra searching.
                IEnumerable <Attribute> attributes = attributeService.Queryable().Where(a =>
                                                                                        _EncryptedAttributeFieldTypes.Contains(a.FieldType.Class) ||
                                                                                        a.DefaultValue.StartsWith("EAAAA")
                                                                                        );

                // Go through each attribute and try re-encrypting it.
                foreach (Attribute attribute in attributes)
                {
                    if (!string.IsNullOrEmpty(attribute.DefaultValue))
                    {
                        string decryptedValue = TryDecrypt(attribute.DefaultValue, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            attribute.DefaultValue = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }
                }

                // Save the attributes
                rockContext.SaveChanges(true);
            }

            context.UpdateLastStatusMessage("Migrating AttributeValue Values");

            // Re-encrypt all AttributeValue Values
            using (RockContext rockContext = new RockContext())
            {
                // Make a new Attribute Value service
                AttributeValueService attributeValueService = new AttributeValueService(rockContext);

                // Get all attribute valuess that have an encrypted DefaultValue
                // Normally we just use the field type to define what's encrypted or not, but System
                // Settings don't have a field type so we have to do a bit of extra searching.
                IEnumerable <AttributeValue> attributeValues = attributeValueService.Queryable()
                                                               .Where(a => a.Value != null && a.Value != "")
                                                               .Where(a => _EncryptedAttributeFieldTypes.Contains(a.Attribute.FieldType.Class) || a.Value.StartsWith("EAAAA"));

                // Track numbers since this will take a while
                int totalCount   = attributeValues.Count();
                int currentCount = 1;

                // Go through each attribute value and try re-encrypting it.
                foreach (AttributeValue attributeValue in attributeValues)
                {
                    if (!string.IsNullOrEmpty(attributeValue.Value))
                    {
                        string decryptedValue = TryDecrypt(attributeValue.Value, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            attributeValue.Value = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Update the status and save every 250 attribute values
                    currentCount++;
                    if (currentCount % 250 == 0)
                    {
                        context.UpdateLastStatusMessage($@"Migrating AttributeValue {currentCount} of {totalCount}");
                    }
                }

                context.UpdateLastStatusMessage($@"Saving AttributeValues");

                // Save the attribute values
                rockContext.SaveChanges(true);
            }

            context.UpdateLastStatusMessage("Migrating encrypted FinancialPaymentDetail fields");

            // Re-encrypt all encrypted FinancialPaymentDetail fields
            using (RockContext rockContext = new RockContext())
            {
                // Make a new Financial Payment Detail service
                FinancialPaymentDetailService financialPaymentDetailService = new FinancialPaymentDetailService(rockContext);

                IEnumerable <FinancialPaymentDetail> financialPaymentDetails = financialPaymentDetailService.Queryable().Where(fpd =>
                                                                                                                               (fpd.ExpirationMonthEncrypted != null && fpd.ExpirationMonthEncrypted != "") ||
                                                                                                                               (fpd.ExpirationYearEncrypted != null && fpd.ExpirationYearEncrypted != "") ||
                                                                                                                               (fpd.NameOnCardEncrypted != null && fpd.NameOnCardEncrypted != "")
                                                                                                                               );

                // Track numbers since this will take a while
                int totalCount   = financialPaymentDetails.Count();
                int currentCount = 1;

                // Go through each financial payment detail and try re-encrypting it.
                foreach (FinancialPaymentDetail financialPaymentDetail in financialPaymentDetails)
                {
                    // Check Expiration Month
                    if (!string.IsNullOrEmpty(financialPaymentDetail.ExpirationMonthEncrypted))
                    {
                        string decryptedValue = TryDecrypt(financialPaymentDetail.ExpirationMonthEncrypted, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            financialPaymentDetail.ExpirationMonthEncrypted = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Check Expiration Year
                    if (!string.IsNullOrEmpty(financialPaymentDetail.ExpirationYearEncrypted))
                    {
                        string decryptedValue = TryDecrypt(financialPaymentDetail.ExpirationYearEncrypted, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            financialPaymentDetail.ExpirationYearEncrypted = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Check Name On Card
                    if (!string.IsNullOrEmpty(financialPaymentDetail.NameOnCardEncrypted))
                    {
                        string decryptedValue = TryDecrypt(financialPaymentDetail.NameOnCardEncrypted, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            financialPaymentDetail.NameOnCardEncrypted = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Update the status and save every 250 financial payment detail
                    currentCount++;
                    if (currentCount % 250 == 0)
                    {
                        context.UpdateLastStatusMessage($@"Migrating FinancialPaymentDetail {currentCount} of {totalCount}");
                    }
                }

                context.UpdateLastStatusMessage($@"Saving FinancialPaymentDetails");

                // Save the financial payment details
                rockContext.SaveChanges(true);
            }

            context.UpdateLastStatusMessage("Migrating encrypted FinancialTransaction fields");

            // Re-encrypt all encrypted FinancialTransaction fields
            using (RockContext rockContext = new RockContext())
            {
                // Make a new Financial Transaction service
                FinancialTransactionService financialTransactionService = new FinancialTransactionService(rockContext);

                IEnumerable <FinancialTransaction> financialTransactions = financialTransactionService.Queryable().Where(ft =>
                                                                                                                         (ft.CheckMicrEncrypted != null && ft.CheckMicrEncrypted != "") ||
                                                                                                                         (ft.CheckMicrParts != null && ft.CheckMicrParts != "")
                                                                                                                         );

                // Track numbers since this will take a while
                int totalCount   = financialTransactions.Count();
                int currentCount = 1;

                // Go through each financial payment detail and try re-encrypting it.
                foreach (FinancialTransaction financialTransaction in financialTransactions)
                {
                    // Check the Check Micr
                    if (!string.IsNullOrEmpty(financialTransaction.CheckMicrEncrypted))
                    {
                        string decryptedValue = TryDecrypt(financialTransaction.CheckMicrEncrypted, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            financialTransaction.CheckMicrEncrypted = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Check the Check Micr Parts
                    if (!string.IsNullOrEmpty(financialTransaction.CheckMicrParts))
                    {
                        string decryptedValue = TryDecrypt(financialTransaction.CheckMicrParts, currentEncryptionKey);
                        if (!string.IsNullOrEmpty(decryptedValue))
                        {
                            financialTransaction.CheckMicrParts = RockCrypto.EncryptString(decryptedValue, newEncryptionKey);
                        }
                    }

                    // Update the status and save every 250 financial payment detail
                    currentCount++;
                    if (currentCount % 250 == 0)
                    {
                        context.UpdateLastStatusMessage($@"Migrating FinancialTransaction {currentCount} of {totalCount}");
                    }
                }

                context.UpdateLastStatusMessage($@"Saving FinancialTransactions");

                // Save the financial transactions
                rockContext.SaveChanges(true);
            }

            context.UpdateLastStatusMessage("Done");

            // Delete the job so it doesn't run again
            using (RockContext rockContext = new RockContext())
            {
                // Make a new Job service
                ServiceJobService jobService = new ServiceJobService(rockContext);

                // Get the current job
                var job = jobService.Get(context.GetJobId());

                // Delete it
                if (job != null)
                {
                    jobService.Delete(job);
                    rockContext.SaveChanges(true);
                }
            }



            // Save the new password
            // This will cause Rock to restart, so it has to be last
            RockCrypto.SetConfiguredEncryptionPassword(newEncryptionPassword);
        }