/// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            // Add new Business Name search component
            RockMigrationHelper.UpdateEntityType("Rock.Search.Person.BusinessName", "Business Name", "Rock.Search.Person.BusinessName, Rock, Version=1.4.4.0, Culture=neutral, PublicKeyToken=null", false, true, "944ACDD0-A4AC-4E5A-8689-E2D8EF773BC2");

            // Add Attributes for Business Name search component
            RockMigrationHelper.AddEntityAttribute("Rock.Search.Person.BusinessName", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "False", "35578D31-13DE-4952-9707-67DBE00D2E37");
            RockMigrationHelper.AddEntityAttribute("Rock.Search.Person.BusinessName", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "", "", "Order", "", "The order that this service should be used (priority)", 0, "", "699D01D2-57B4-499B-BB98-B773EF343A30");
            RockMigrationHelper.AddEntityAttribute("Rock.Search.Person.BusinessName", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Result URL", "", "The url to redirect user to after they have entered search text.  (use '{0}' for the search text)", 0, "", "1ECEF3CD-0B36-4669-AFA7-72D6A79C1536");
            RockMigrationHelper.AddEntityAttribute("Rock.Search.Person.BusinessName", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Search Label", "", "The text to display in the search type dropdown", 0, "Search", "70321846-B028-40AB-A41F-84AD8A88933C");

            // Add Attribute Values
            RockMigrationHelper.AddAttributeValue("70321846-B028-40AB-A41F-84AD8A88933C", 0, @"Business", "70321846-B028-40AB-A41F-84AD8A88933C");                             // Search Label
            RockMigrationHelper.AddAttributeValue("1ECEF3CD-0B36-4669-AFA7-72D6A79C1536", 0, @"Business/Search/name/?SearchTerm={0}", "1ECEF3CD-0B36-4669-AFA7-72D6A79C1536"); // Result URL
            RockMigrationHelper.AddAttributeValue("699D01D2-57B4-499B-BB98-B773EF343A30", 0, @"5", "699D01D2-57B4-499B-BB98-B773EF343A30");                                    // Order
            RockMigrationHelper.AddAttributeValue("35578D31-13DE-4952-9707-67DBE00D2E37", 0, @"True", "35578D31-13DE-4952-9707-67DBE00D2E37");                                 // Active

            // Add a route to the Business List page for the search results
            RockMigrationHelper.AddPageRoute("F4DF4899-2D44-4997-BA9B-9D2C64958A20", "Business/Search/{SearchType}", "A105F0F9-3EAA-4EA8-94B0-394370DFB810");

            // Secure the Rock.Search.Person.BusinessName component (408 TODO change to Guid)
            RockMigrationHelper.AddSecurityAuthForEntityType("Rock.Search.Person.BusinessName", 1, "View", true, "6246A7EF-B7A3-4C8C-B1E4-3FF114B84559", 0, "052AF751-BF8B-49AE-BA4A-72C88119BECA"); // EntityType:Rock.Search.Person.BusinessName Group: 6246A7EF-B7A3-4C8C-B1E4-3FF114B84559 ( RSR - Finance Administration ),
            RockMigrationHelper.AddSecurityAuthForEntityType("Rock.Search.Person.BusinessName", 2, "View", true, "2539CF5D-E2CE-4706-8BBF-4A9DF8E763E9", 0, "42F0D039-65F3-4262-AB18-7EFDE30FDB92"); // EntityType:Rock.Search.Person.BusinessName Group: 2539CF5D-E2CE-4706-8BBF-4A9DF8E763E9 ( RSR - Finance Worker ),
            RockMigrationHelper.AddSecurityAuthForEntityType("Rock.Search.Person.BusinessName", 3, "View", false, "", 1, "1FF24243-FF2E-4FF5-B671-D54AAC4423AF");                                    // EntityType:Rock.Search.Person.BusinessName Group: <all users>
            RockMigrationHelper.AddSecurityAuthForEntityType("Rock.Search.Person.BusinessName", 0, "View", true, "628C51A8-4613-43ED-A18D-4A6FB999273E", 0, "D5476011-1B24-4A05-A61D-665DBD1B8379"); // EntityType:Rock.Search.Person.BusinessName Group: 628C51A8-4613-43ED-A18D-4A6FB999273E ( RSR - Rock Administration ),
        }
        public override void Up()
        {
            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications' AND [Guid] = '895C301C-02D1-4D9C-9FC4-DA7257368208' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,1
                  ,'Care Need Automated Notifications'
                  ,''
                  ,'rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications'
                  ,'0 15 2 1/1 * ? *'
                  ,1
                  ,'895C301C-02D1-4D9C-9FC4-DA7257368208'
                  );
            END");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Follow Up Notification Template
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "72ED40C7-4D64-4D60-9411-4FFB2B9E833E", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Follow Up Notification Template", "Follow Up Notification Template", @"The system communication to use when sending the Care Need Follow Up.", 0, "", "125F5EB3-8223-40B9-8FD6-4EED93602D72", "FollowUpSystemCommunication");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Care Touch Needed Notification Template
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "72ED40C7-4D64-4D60-9411-4FFB2B9E833E", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Care Touch Needed Notification Template", "Care Touch Needed Notification Template", @"The system communication to use when sending the Care Touch needed notification.", 0, "", "8D050C0F-105B-4A8B-8879-A15F78F5913E", "CareTouchNeededCommunication");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Outstanding Needs Notification Template
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "72ED40C7-4D64-4D60-9411-4FFB2B9E833E", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Outstanding Needs Notification Template", "Outstanding Needs Notification Template", @"The system communication to use when sending the Outstanding Care Needs notification.", 0, "", "08D1BB81-9FCA-488B-9383-9440D1DCCFC6", "OutstandingNeedsCommunication");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Minimum Care Touches
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Minimum Care Touches", "Minimum Care Touches", @"Minimum care touches in 24 hours before the Care Touch needed notification gets sent out.", 0, @"2", "A29278C1-9A80-4BEA-81A9-1B7FCB6CA305", "MinimumCareTouches");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Follow Up Days
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Follow Up Days", "Follow Up Days", @"Days after a Care Need has been entered before it changes status to Follow Up.", 0, @"10", "F64479EE-A595-4AA3-97D6-CAA768464284", "FollowUpDays");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Care Dashboard Page
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "BD53F9C9-EBA9-4D3F-82EA-DE5DD34A8108", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Care Dashboard Page", "Care Dashboard Page", @"Page used to populate 'LinkedPages.CareDashboard' lava field in notification.", 0, @"", "5D8548E7-9570-4337-888B-A51868A57CD0", "CareDashboardPage");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Care Detail Page
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "BD53F9C9-EBA9-4D3F-82EA-DE5DD34A8108", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Care Detail Page", "Care Detail Page", @"Page used to populate 'LinkedPages.CareDetail' lava field in notification.", 0, @"", "245DFE71-FF8D-41FE-91A8-E4D29B1AF016", "CareDetailPage");
            // Attribute: rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications: Minimum Care Touch Hours
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "rocks.kfs.StepsToCare.Jobs.CareNeedAutomatedNotifications", "Minimum Care Touch Hours", "Minimum Care Touch Hours", @"Minimum care touches in this time period before the Care Touch needed notification gets sent out.", 0, @"24", "AF3ECA88-C715-4E2D-9D9B-C4CC3141C6EC", "MinimumCareTouchesHours");

            RockMigrationHelper.AddAttributeValue("125F5EB3-8223-40B9-8FD6-4EED93602D72", -1, SystemGuid.SystemCommunication.CARE_NEED_FOLLOWUP, "DEF6F4F3-B4EC-4F2F-A996-C30212D48DBA");          // Care Need Automated Notifications: Follow Up Notification Template
            RockMigrationHelper.AddAttributeValue("8D050C0F-105B-4A8B-8879-A15F78F5913E", -1, SystemGuid.SystemCommunication.CARE_NEED_TOUCH_NEEDED, "D4C73B39-5658-4B93-9A62-31DBF1A89EF4");      // Care Need Automated Notifications: Care Touch Needed Notification Template
            RockMigrationHelper.AddAttributeValue("08D1BB81-9FCA-488B-9383-9440D1DCCFC6", -1, SystemGuid.SystemCommunication.CARE_NEED_OUTSTANDING_NEEDS, "EF10B5FA-3164-4BC4-8750-E33B9CAA75A8"); // Care Need Automated Notifications: Outstanding Needs Notification Template
            RockMigrationHelper.AddAttributeValue("A29278C1-9A80-4BEA-81A9-1B7FCB6CA305", -1, @"2", "71D37170-2B1B-4C36-A853-0B64737C2518");                                                       // Care Need Automated Notifications: Minimum Care Touches
            RockMigrationHelper.AddAttributeValue("F64479EE-A595-4AA3-97D6-CAA768464284", -1, @"10", "E471BFBB-4E50-4F36-801E-7F2F6FC7C417");                                                      // Care Need Automated Notifications: Follow Up Days
            RockMigrationHelper.AddAttributeValue("5D8548E7-9570-4337-888B-A51868A57CD0", -1, @"1f93e9aa-ecca-42a2-8c91-73d991dbcd9f", "F7218A61-0324-467B-AD5B-C9C58030EA95");                    // Care Need Automated Notifications: Care Dashboard Page
            RockMigrationHelper.AddAttributeValue("245DFE71-FF8D-41FE-91A8-E4D29B1AF016", -1, @"27953b65-21e2-4ca9-8461-3afad46d9bc8", "78C13C31-23A4-46F4-B9B1-1815E78A5016");                    // Care Need Automated Notifications: Care Detail Page
            RockMigrationHelper.AddAttributeValue("AF3ECA88-C715-4E2D-9D9B-C4CC3141C6EC", -1, @"24", "79A2352F-D7FB-4BDA-957B-F32D1A10D1D1");                                                      // Care Need Automated Notifications: Minimum Care Touch Hours

            Sql(@"DECLARE @JobId int = ( SELECT TOP 1 [Id] FROM [ServiceJob] WHERE [Guid] = '895C301C-02D1-4D9C-9FC4-DA7257368208' )
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = 'DEF6F4F3-B4EC-4F2F-A996-C30212D48DBA'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = 'D4C73B39-5658-4B93-9A62-31DBF1A89EF4'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = 'EF10B5FA-3164-4BC4-8750-E33B9CAA75A8'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = '71D37170-2B1B-4C36-A853-0B64737C2518'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = 'E471BFBB-4E50-4F36-801E-7F2F6FC7C417'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = 'F7218A61-0324-467B-AD5B-C9C58030EA95'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = '78C13C31-23A4-46F4-B9B1-1815E78A5016'
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] = '79A2352F-D7FB-4BDA-957B-F32D1A10D1D1'");                                                                            // Set EntityId to proper Job id
        }
        private void UpAddServiceJobs()
        {
            /* Service Jobs*/
            // add ServiceJob: Process Group History
            // Code Generated using Rock\Dev Tools\Sql\CodeGen_ServiceJobWithAttributes_ForAJob.sql
            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'Rock.Jobs.ProcessGroupHistory' AND [Guid] = 'D81E577D-2D87-4CEB-9585-7BA8DBA0F556' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,1
                  ,'Process Group History'
                  ,'Creates Historical snapshots of Groups and Group Members for any group types that have history enabled.'
                  ,'Rock.Jobs.ProcessGroupHistory'
                  ,'0 30 3 1/1 * ? *'
                  ,1
                  ,'D81E577D-2D87-4CEB-9585-7BA8DBA0F556'
                  );
            END");


            // add ServiceJob: Migrate History Summary Data (schedule for 9pm to avoid conflict with AppPoolRecycle)
            // Code Generated using Rock\Dev Tools\Sql\CodeGen_ServiceJobWithAttributes_ForAJob.sql
            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'Rock.Jobs.MigrateHistorySummaryData' AND [Guid] = 'CF2221CC-1E0A-422B-B0F7-5D81AF1DDB14' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,1
                  ,'Migrate History Summary Data'
                  ,'Migrates History Summary Text into separate columns: Verb, ChangeType, OldValue, NewValue, etc. This will enable the new v8 History UIs to do cool things. When this job is done migrating all the data, it will delete itself.'
                  ,'Rock.Jobs.MigrateHistorySummaryData'
                  ,'0 0 21 1/1 * ? *'
                  ,1
                  ,'CF2221CC-1E0A-422B-B0F7-5D81AF1DDB14'
                  );
            END");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "Rock.Jobs.MigrateHistorySummaryData", "How Many Records", "The number of history records to process on each run of this job.", 0, @"500000", "FAC124D5-7C16-4AE9-9631-EF087349476F", "HowMany");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "Rock.Jobs.MigrateHistorySummaryData", "Command Timeout", "Maximum amount of time (in seconds) to wait for the SQL Query to complete. Leave blank to use the default for this job (3600). Note, it could take several minutes, so you might want to set it at 3600 (60 minutes) or higher", 1, @"3600", "1F28861F-99C2-4EAC-B7F7-4AE60018D97E", "CommandTimeout");
            RockMigrationHelper.AddAttributeValue("FAC124D5-7C16-4AE9-9631-EF087349476F", 39, @"500000", "FAC124D5-7C16-4AE9-9631-EF087349476F"); // Migrate History Summary Data: How Many Records
            RockMigrationHelper.AddAttributeValue("1F28861F-99C2-4EAC-B7F7-4AE60018D97E", 39, @"3600", "1F28861F-99C2-4EAC-B7F7-4AE60018D97E");   // Migrate History Summary Data: Command Timeout
        }
        public override void Up()
        {
            // Register your custom ReportTemplate "entity type"... that last item on this next line is your own custom GUID.
            RockMigrationHelper.UpdateEntityType("org.rocksolidchurch.RoomManagementTemplates.SampleReportTemplate", "RockSolidChurch SampleExample Report Template", "org.rocksolidchurch.RoomManagementTemplates.SampleReportTemplate, org.rocksolidchurch.RoomManagementTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", false, true, "A76C387A-96EA-475C-81D9-ABD73C049E01");   // use your own custom GUID

            // Register the IsActive attribute for your custom report.  The last item on this next line is another new custom GUID for your attribute.
            RockMigrationHelper.AddEntityAttribute("org.rocksolidchurch.RoomManagementTemplates.SampleReportTemplate", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "62EC758F-6DD8-47EF-A5C7-F1786AAC6DE4");   // yep, your own custom guid is the last item here.

            // Now set the IsActive value to True on that new attribute you just added.
            RockMigrationHelper.AddAttributeValue("62EC758F-6DD8-47EF-A5C7-F1786AAC6DE4", 0, "True", Guid.NewGuid().ToString());
        }
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            RockMigrationHelper.UpdateCategory("546D5F43-1184-47C9-8265-2D7BF4E1BCA5", "Financial", "", "", "E41FC407-B60E-4B85-954D-D27F0762114B", 0);
            RockMigrationHelper.UpdateCategory("546D5F43-1184-47C9-8265-2D7BF4E1BCA5", "Batch", "fa fa-archive", "", "AF6A8CFF-F24F-4AA8-B126-94B6903961C0", 0, "E41FC407-B60E-4B85-954D-D27F0762114B");
            RockMigrationHelper.UpdateCategory("546D5F43-1184-47C9-8265-2D7BF4E1BCA5", "Transaction", "fa fa-credit-card", "", "477EE3BE-C68F-48BD-B218-FAFC99AF56B3", 1, "E41FC407-B60E-4B85-954D-D27F0762114B");

            Sql(@"
    DECLARE @UrlMaskAttributeId int = ( SELECT TOP 1 [Id] FROM [Attribute] WHERE [Guid] = '0C405062-72BB-4362-9738-90C9ED5ACDDE' )
    DECLARE @TransactionCategoryId int = ( SELECT TOP 1 [Id] FROM [Category] WHERE [Guid] = '477EE3BE-C68F-48BD-B218-FAFC99AF56B3' )
    DECLARE @TransactionDetailPageId int = ( SELECT TOP 1 [Id] FROM [Page] WHERE [Guid] = '97716641-D003-4663-9EA2-D9BB94E7955B' )
    IF @UrlMaskAttributeId IS NOT NULL AND @TransactionCategoryId IS NOT NULL AND @TransactionDetailPageId IS NOT NULL
    BEGIN

        DELETE [AttributeValue]
        WHERE [AttributeId] = @UrlMaskAttributeId
        AND [EntityId] = @TransactionCategoryId

        INSERT INTO [AttributeValue] ([IsSystem],[AttributeId],[EntityId],[Value],[Guid] )
        VALUES( 0, @UrlMaskAttributeId, @TransactionCategoryId, '~/page/' + CAST(@TransactionDetailPageId AS varchar) + '?batchId={1}&transactionId={0}', NEWID())
    END
");

            RockMigrationHelper.AddPage("606BDA31-A8FE-473A-B3F8-A00ECF7E06EC", "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Audit Log", "", "CBE0C5ED-744E-4392-A9D4-0DC57AF11D33", "fa fa-file-text-o");   // Site:Rock RMS
            RockMigrationHelper.UpdateBlockType("History Log", "Block for displaying the history of changes to a particular entity.", "~/Blocks/Core/HistoryLog.ascx", "Core", "C6C2DF41-A50D-4975-B21C-4EFD6FF3E8D0");

            // Add Block to Page: Audit Log, Site: Rock RMS
            RockMigrationHelper.AddBlock("CBE0C5ED-744E-4392-A9D4-0DC57AF11D33", "", "C6C2DF41-A50D-4975-B21C-4EFD6FF3E8D0", "History Log", "Main", "", "", 0, "39F5EA5A-6F78-4A4F-ABFE-719DD75B445A");

            // Attrib for BlockType: Batch Detail:Audit Page
            RockMigrationHelper.AddBlockTypeAttribute("CE34CE43-2CCF-4568-9AEB-3BE203DB3470", "BD53F9C9-EBA9-4D3F-82EA-DE5DD34A8108", "Audit Page", "AuditPage", "", "Page used to display the history of changes to a batch.", 0, @"", "66E7C23A-797D-4945-931F-DC7671C79AC1");

            // Attrib for BlockType: History Log:Entity Type
            RockMigrationHelper.AddBlockTypeAttribute("C6C2DF41-A50D-4975-B21C-4EFD6FF3E8D0", "3549BAB6-FE1B-4333-AFC4-C5ACA01BB8EB", "Entity Type", "ContextEntityType", "", "The type of entity that will provide context for this block", 0, @"", "8FB690EC-5299-46C5-8695-AAD23168E6E1");

            // Attrib Value for Block:Batch Detail, Attribute:Audit Page Page: Financial Batch Detail, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("E7C8C398-0E1D-4BCE-BC54-A02957228514", "66E7C23A-797D-4945-931F-DC7671C79AC1", @"cbe0c5ed-744e-4392-a9d4-0dc57af11d33");

            // Attrib Value for Block:History Log, Attribute:Entity Type Page: Audit Log, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("39F5EA5A-6F78-4A4F-ABFE-719DD75B445A", "8FB690EC-5299-46C5-8695-AAD23168E6E1", @"bdd09c8e-2c52-4d08-9062-be7d52d190c2");

            // Add/Update PageContext for Page:Audit Log, Entity: Rock.Model.FinancialBatch, Parameter: BatchId
            RockMigrationHelper.UpdatePageContext("CBE0C5ED-744E-4392-A9D4-0DC57AF11D33", "Rock.Model.FinancialBatch", "BatchId", "307639F5-824A-453C-8650-B393DEC506F1");

            // PIN Auth Enable
            RockMigrationHelper.UpdateEntityType("Rock.Security.Authentication.PINAuthentication", "PIN Authentication", "Rock.Security.Authentication.PINAuthentication, Rock, Version=1.3.4.0, Culture=neutral, PublicKeyToken=null", false, true, "1FB5A259-F45C-4857-AF3D-3B9E32DB0EEE");
            RockMigrationHelper.AddEntityAttribute("Rock.Security.Authentication.PINAuthentication", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "F8926E80-1CD1-4DFD-AC1F-28B5DC75B207");
            RockMigrationHelper.AddAttributeValue("F8926E80-1CD1-4DFD-AC1F-28B5DC75B207", 0, "True", "F422DAF8-E84F-4678-B179-DD4EF83E2585");
        }
Esempio n. 6
0
        public override void Up()
        {
            // Report Templates
            RockMigrationHelper.UpdateEntityType("rocks.kfs.RoomManagement.ReportTemplates.LavaLandscapeReportTemplate", "KFS - Lava Landscape Template", "rocks.kfs.RoomManagement.ReportTemplates.LavaLandscapeReportTemplate, rocks.kfs.RoomManagement.ReportTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", false, true, "1676d165-61e9-4a3f-abd6-01904afa2ceb");
            RockMigrationHelper.UpdateEntityType("rocks.kfs.RoomManagement.ReportTemplates.SPACReportTemplate", "KFS - SPAC Template", "rocks.kfs.RoomManagement.ReportTemplates.SPACReportTemplate, rocks.kfs.RoomManagement.ReportTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", false, true, "56288405-fb95-41c2-a2e4-775265c15f19");
            RockMigrationHelper.UpdateEntityType("rocks.kfs.RoomManagement.ReportTemplates.ResourceQuestionReportTemplate", "KFS - Resource Question Template", "rocks.kfs.RoomManagement.ReportTemplates.ResourceQuestionReportTemplate, rocks.kfs.RoomManagement.ReportTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", false, true, "2b2aff9a-c454-415c-ba68-01a4f18559ca");

            RockMigrationHelper.AddEntityAttribute("rocks.kfs.RoomManagement.ReportTemplates.LavaLandscapeReportTemplate", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "5914141D-0DA5-47E1-B86D-697A2F09AD8F");
            RockMigrationHelper.AddAttributeValue("5914141D-0DA5-47E1-B86D-697A2F09AD8F", 0, "True", "5D1C0EA8-67B6-45EE-ACAB-4A58AD0587D6");

            RockMigrationHelper.AddEntityAttribute("rocks.kfs.RoomManagement.ReportTemplates.SPACReportTemplate", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "5D02961E-3320-4087-9CBB-1501DDEDBC80");
            RockMigrationHelper.AddAttributeValue("5D02961E-3320-4087-9CBB-1501DDEDBC80", 0, "True", "D70BF65C-CABC-45C7-9FAF-DF310C57FBFE");

            RockMigrationHelper.AddEntityAttribute("rocks.kfs.RoomManagement.ReportTemplates.ResourceQuestionReportTemplate", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "CC6AB638-EDFD-4901-B73B-69D1CA29120C");
            RockMigrationHelper.AddAttributeValue("CC6AB638-EDFD-4901-B73B-69D1CA29120C", 0, "True", "D4FFBF1D-B7C0-4187-A654-3F56109083D8");
        }
Esempio n. 7
0
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            DropIndex("dbo.AttendanceOccurrence", new[] { "SundayDate" });
            DropColumn("dbo.AttendanceOccurrence", "SundayDate");
            AddColumn("dbo.AttendanceOccurrence", "SundayDate", c => c.DateTime(nullable: false, storeType: "date", defaultValue: SqlDateTime.MinValue.Value));
            CreateIndex("dbo.AttendanceOccurrence", "SundayDate");

            DropIndex("dbo.FinancialTransaction", new[] { "SundayDate" });
            DropColumn("dbo.FinancialTransaction", "SundayDate");
            AddColumn("dbo.FinancialTransaction", "SundayDate", c => c.DateTime(nullable: true, storeType: "date", defaultValue: SqlDateTime.MinValue.Value));


            CreateIndex("dbo.FinancialTransaction", "SundayDate");

            // add ServiceJob: SundayDate Data Migrations for v10.0
            // Code Generated using Rock\Dev Tools\Sql\CodeGen_ServiceJobWithAttributes_ForAJob.sql
            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'Rock.Jobs.PostV100DataMigrationsSundayDate' AND [Guid] = 'CC263453-B290-4393-BB91-1C1C87CAE291' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,1
                  ,'SundayDate Data Migrations for v10.0'
                  ,'This job will take care of any data migrations to SundayDate on AttendanceOccurrence and FinancialTransaction that need to occur after updating to v10.0. After all the operations are done, this job will delete itself.'
                  ,'Rock.Jobs.PostV100DataMigrationsSundayDate'
                  ,'0 0 2 1/1 * ? *'
                  ,1
                  ,'CC263453-B290-4393-BB91-1C1C87CAE291'
                  );
            END");

            // Attribute: Rock.Jobs.PostV100DataMigrationsSundayDate: Command Timeout
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "Rock.Jobs.PostV100DataMigrationsSundayDate", "Command Timeout", "Command Timeout", @"Maximum amount of time (in seconds) to wait for each SQL command to complete. On a large database with lots of transactions, this could take several minutes or more.", 0, @"3600", "13D4DAF9-BDD0-4D1A-B511-F69AAF565DCD", "CommandTimeout");
            RockMigrationHelper.AddAttributeValue("13D4DAF9-BDD0-4D1A-B511-F69AAF565DCD", 56, @"3600", "13D4DAF9-BDD0-4D1A-B511-F69AAF565DCD");   // SundayDate Data Migrations for v10.0: Command Timeout
        }
Esempio n. 8
0
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "Active", "Active", "Should Service be used?", 0, @"False", "6BEBD4BE-EDC7-4757-B597-445FC60DB6ED");                                                                                                                                                 // Rock.Workflow.Action.BackgroundCheckRequest:Active
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "33E6DF69-BDFA-407A-9744-C175B60643AE", "Billing Code Attribute", "BillingCodeAttribute", "The attribute that contains the billing code to use when submitting background check.", 4, @"", "232B2F98-3B2F-4C53-81FC-061A92675C41");                                                          // Rock.Workflow.Action.BackgroundCheckRequest:Billing Code Attribute
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "33E6DF69-BDFA-407A-9744-C175B60643AE", "Person Attribute", "PersonAttribute", "The Person attribute that contains the person who the background check should be submitted for.", 1, @"", "077A9C4E-86E7-42F6-BEC3-DBC8F57E6A13");                                                           // Rock.Workflow.Action.BackgroundCheckRequest:Person Attribute
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "33E6DF69-BDFA-407A-9744-C175B60643AE", "Request Type Attribute", "RequestTypeAttribute", "The attribute that contains the type of background check to submit (Specific to provider).", 3, @"", "EC759165-949E-4966-BAFD-68A656A4EBF7");                                                     // Rock.Workflow.Action.BackgroundCheckRequest:Request Type Attribute
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "33E6DF69-BDFA-407A-9744-C175B60643AE", "SSN Attribute", "SSNAttribute", "The attribute that contains the Social Security Number of the person who the background check should be submitted for ( Must be an 'Encrypted Text' attribute )", 2, @"", "2631E72B-1D9B-40E8-B857-8B1D41943451"); // Rock.Workflow.Action.BackgroundCheckRequest:SSN Attribute
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "A7486B0E-4CA2-4E00-A987-5544C7DABA76", "Background Check Provider", "Provider", "The Background Check provider to use", 0, @"", "6E2366B4-9F0E-454A-9DB1-E06263749C12");                                                                                                                    // Rock.Workflow.Action.BackgroundCheckRequest:Background Check Provider
            RockMigrationHelper.UpdateWorkflowActionEntityAttribute("C4DAE3D6-931F-497F-AC00-60BAFA87B758", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Order", "Order", "The order that this service should be used (priority)", 0, @"", "3936E931-CC27-4C38-9AA5-AAA502057333");                                                                                                                          // Rock.Workflow.Action.BackgroundCheckRequest:Order

            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "6BEBD4BE-EDC7-4757-B597-445FC60DB6ED", @"False");                                                                                                                                                                                                                                                   // Background Check:Submit Request:Submit Request:Active
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "6E2366B4-9F0E-454A-9DB1-E06263749C12", @"8d9de88a-c649-47b2-ba5c-92a24f60ae61");                                                                                                                                                                                                                    // Background Check:Submit Request:Submit Request:Background Check Provider
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "3936E931-CC27-4C38-9AA5-AAA502057333", @"");                                                                                                                                                                                                                                                        // Background Check:Submit Request:Submit Request:Order
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "077A9C4E-86E7-42F6-BEC3-DBC8F57E6A13", @"2d977682-2589-47bb-94e6-906a9587ee7c");                                                                                                                                                                                                                    // Background Check:Submit Request:Submit Request:Person Attribute
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "2631E72B-1D9B-40E8-B857-8B1D41943451", @"");                                                                                                                                                                                                                                                        // Background Check:Submit Request:Submit Request:SSN Attribute
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "EC759165-949E-4966-BAFD-68A656A4EBF7", @"00b8c76c-0fff-4827-8abc-48215004686f");                                                                                                                                                                                                                    // Background Check:Submit Request:Submit Request:Request Type Attribute
            RockMigrationHelper.AddActionTypeAttributeValue("70DABC23-6587-4F18-8551-C655AA285F44", "232B2F98-3B2F-4C53-81FC-061A92675C41", @"c4c12a1e-26b7-4580-b70c-baf64497f3e8");                                                                                                                                                                                                                    // Background Check:Submit Request:Submit Request:Billing Code Attribute

            RockMigrationHelper.AddEntityAttribute("Rock.Checkr.Checkr", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "", "0ac1596b-0143-4939-aacd-0b14f6f74322");
            RockMigrationHelper.AddAttributeValue("0ac1596b-0143-4939-aacd-0b14f6f74322", 0, "True", "554468D0-A891-5281-4D08-FED46D756E28");
        }
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            #region Zoom Room Scheduling and Maintenance Job

            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance' AND [Guid] = 'B23BD7D6-046D-411D-8F06-64EE237FA770' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,0
                  ,'Zoom Room Reservation Scheduling and Maintenance'
                  ,'Generates Zoom Room occurrences and synchronizes meeting schedules for Room Reservations tied to Locations linked to a Zoom Room.'
                  ,'rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance'
                  ,'0 0 0/1 1/1 * ? *'  -- Every Hour
                  ,1
                  ,'B23BD7D6-046D-411D-8F06-64EE237FA770'
                  );
            END");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance: Sync Days Out
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.INTEGER, "Class", "rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance", "Sync Days Out", "SyncDaysOut", @"Number of days into the future to sync Locations to Zoom Rooms if the Schedule does not have an effective date.", 1, @"30", "4504E3F4-E2E1-44DB-B6D7-E2CC1F498695", "SyncDaysOut");
            RockMigrationHelper.AddAttributeValue("4504E3F4-E2E1-44DB-B6D7-E2CC1F498695", -1, @"30", "43FF6707-E0C9-4303-804D-48587EDD20D0");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance: Enable Verbose Logging
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.BOOLEAN, "Class", "rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance", "Enable Verbose Logging", "Verbose Logging", @"Turn on extra logging points in addition to the standard job logging points. This is only recommended for testing/troubleshooting purposes.", 2, bool.FalseString, "6EE5573F-D3CE-4E04-A9D7-EF6F19343961", "VerboseLogging");
            RockMigrationHelper.AddAttributeValue("6EE5573F-D3CE-4E04-A9D7-EF6F19343961", -1, bool.FalseString, "D5CEA4A8-54A4-4790-926F-A93423471BA0");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance: Import Zoom Room Meetings
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.BOOLEAN, "Class", "rocks.kfs.Zoom.Jobs.ZoomRoomSchedulingAndMaintenance", "Import Zoom Room Meetings", "Import Zoom Room Meetings", @"Create Room Reservations for any Zoom Room meetings scheduled outside of Rock. This will help reduce the chances of the Room Reservation plugin scheduling a conflict with other Zoom Room meetings.", 3, bool.FalseString, "E512BF8F-EBD0-40D9-B310-3C3B3B895629", "ImportMeetings");
            RockMigrationHelper.AddAttributeValue("E512BF8F-EBD0-40D9-B310-3C3B3B895629", -1, bool.FalseString, "7D96AD5A-29A6-40F0-BF1D-1D6EEEA26A8C");

            Sql(@"DECLARE @JobId int = ( SELECT TOP 1 [Id] FROM [ServiceJob] WHERE [Guid] = 'B23BD7D6-046D-411D-8F06-64EE237FA770' )
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] IN ( '43FF6707-E0C9-4303-804D-48587EDD20D0', 'D5CEA4A8-54A4-4790-926F-A93423471BA0', '7D96AD5A-29A6-40F0-BF1D-1D6EEEA26A8C' )");  // Set EntityId to proper Job id

            #endregion Zoom Room Scheduling and Maintenance Job

            #region Zoom Meeting Reminder Job

            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder' AND [Guid] = '07BCC7E6-0E02-4ECE-8948-422C4E4EF20D' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,0
                  ,'Zoom Meeting Group Reminder'
                  ,'Sends a reminder to members of a group connected with a room reservation that has a Zoom meeting attached to it.'
                  ,'rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder'
                  ,'0 0 5 1/1 * ? *' -- Daily at 5:00 AM
                  ,1
                  ,'07BCC7E6-0E02-4ECE-8948-422C4E4EF20D'
                  );
            END");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder: System Communication
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.SYSTEM_COMMUNICATION, "Class", "rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder", "System Communication", "System Communication", @"The system communication to use when sending Zoom meeting reminders.", 1, ZoomGuid.SystemComunication.ZOOM_MEETING_REMINDER, "00D58FC1-E85B-4D6F-8788-3F9466A8A364", "SystemCommunication");
            RockMigrationHelper.AddAttributeValue("00D58FC1-E85B-4D6F-8788-3F9466A8A364", -1, ZoomGuid.SystemComunication.ZOOM_MEETING_REMINDER, "5AD2F8A7-B809-4479-A118-1B36623DBFC0");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder: Days Prior
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.TEXT, "Class", "rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder", "Days Prior", "Days Prior", @"Comma delimited list of days prior to a scheduled Zoom meeting to send a reminder. For example, a value of '2,4' would result in reminders getting sent two and four days prior to the Zoom meeting's scheduled meeting date.", 2, "1", "BFE626AD-7141-4EA3-B5CE-73F03FE18622", "DaysPrior");
            RockMigrationHelper.AddAttributeValue("BFE626AD-7141-4EA3-B5CE-73F03FE18622", -1, "1", "DA386BCA-3EDC-4E79-98DB-009C994D2B58");

            // Attribute: rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder: Reminder Group Attribute
            RockMigrationHelper.AddOrUpdateEntityAttribute("Rock.Model.ServiceJob", Rock.SystemGuid.FieldType.ATTRIBUTE, "Class", "rocks.kfs.Zoom.Jobs.ZoomMeetingGroupReminder", "Reminder Group Attribute", "Reminder Group", "The \"Group Type Group\" type attribute on the Room Reservation entity to be used for sending reminders. This attribute is what connects a Room Reservation to a Group for Zoom meeting purposes.", 3, ZoomGuid.Attribute.ROOM_RESERVATION_GROUP_ATTRIBUTE, "866D68EC-835E-4B2A-A2AC-791973D3B4A1", "GroupAttributeSetting");
            RockMigrationHelper.AddAttributeQualifier("866D68EC-835E-4B2A-A2AC-791973D3B4A1", "entitytype", "839768A3-10D6-446C-A65B-B8F9EFD7808F", "C30C97A0-2978-41E2-9F2C-EDF614CB9E22");    // Value parameter is BEMA Room Management system guid for Reservation entity type
            RockMigrationHelper.AddAttributeValue("866D68EC-835E-4B2A-A2AC-791973D3B4A1", -1, ZoomGuid.Attribute.ROOM_RESERVATION_GROUP_ATTRIBUTE, "385C7944-9010-4DB1-9DA1-E4BD0F552C3A");

            Sql(@"DECLARE @JobId int = ( SELECT TOP 1 [Id] FROM [ServiceJob] WHERE [Guid] = '07BCC7E6-0E02-4ECE-8948-422C4E4EF20D' )
                 UPDATE [AttributeValue] SET EntityId = @JobId WHERE [Guid] IN ( '5AD2F8A7-B809-4479-A118-1B36623DBFC0', 'DA386BCA-3EDC-4E79-98DB-009C994D2B58', '385C7944-9010-4DB1-9DA1-E4BD0F552C3A' )");  // Set EntityId to proper Job id

            #endregion Zoom Meeting Reminder Job
        }
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            CreateTable(
                "dbo.NoteWatch",
                c => new
            {
                Id                      = c.Int(nullable: false, identity: true),
                NoteTypeId              = c.Int(),
                EntityTypeId            = c.Int(),
                EntityId                = c.Int(),
                NoteId                  = c.Int(),
                IsWatching              = c.Boolean(nullable: false),
                WatchReplies            = c.Boolean(nullable: false),
                AllowOverride           = c.Boolean(nullable: false),
                WatcherPersonAliasId    = c.Int(),
                WatcherGroupId          = c.Int(),
                CreatedDateTime         = c.DateTime(),
                ModifiedDateTime        = c.DateTime(),
                CreatedByPersonAliasId  = c.Int(),
                ModifiedByPersonAliasId = c.Int(),
                Guid                    = c.Guid(nullable: false),
                ForeignId               = c.Int(),
                ForeignGuid             = c.Guid(),
                ForeignKey              = c.String(maxLength: 100),
            })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.PersonAlias", t => t.CreatedByPersonAliasId)
            .ForeignKey("dbo.EntityType", t => t.EntityTypeId, cascadeDelete: true)
            .ForeignKey("dbo.PersonAlias", t => t.ModifiedByPersonAliasId)
            .ForeignKey("dbo.Note", t => t.NoteId, cascadeDelete: true)
            .ForeignKey("dbo.NoteType", t => t.NoteTypeId)
            .ForeignKey("dbo.Group", t => t.WatcherGroupId, cascadeDelete: true)
            .ForeignKey("dbo.PersonAlias", t => t.WatcherPersonAliasId, cascadeDelete: true)
            .Index(t => t.NoteTypeId)
            .Index(t => t.EntityTypeId)
            .Index(t => t.NoteId)
            .Index(t => t.WatcherPersonAliasId)
            .Index(t => t.WatcherGroupId)
            .Index(t => t.CreatedByPersonAliasId)
            .Index(t => t.ModifiedByPersonAliasId)
            .Index(t => t.Guid, unique: true);

            AddColumn("dbo.Note", "ParentNoteId", c => c.Int());
            AddColumn("dbo.Note", "ApprovalStatus", c => c.Int(nullable: false));
            AddColumn("dbo.Note", "ApprovedByPersonAliasId", c => c.Int());
            AddColumn("dbo.Note", "ApprovedDateTime", c => c.DateTime());
            AddColumn("dbo.Note", "NotificationsSent", c => c.Boolean(nullable: false));
            AddColumn("dbo.Note", "ApprovalsSent", c => c.Boolean(nullable: false));
            AddColumn("dbo.Note", "NoteUrl", c => c.String());
            AddColumn("dbo.Note", "EditedDateTime", c => c.DateTime());
            AddColumn("dbo.Note", "EditedByPersonAliasId", c => c.Int());
            AddColumn("dbo.NoteType", "RequiresApprovals", c => c.Boolean(nullable: false));
            AddColumn("dbo.NoteType", "AllowsWatching", c => c.Boolean(nullable: false));
            AddColumn("dbo.NoteType", "AllowsReplies", c => c.Boolean(nullable: false));
            AddColumn("dbo.NoteType", "MaxReplyDepth", c => c.Int());
            AddColumn("dbo.NoteType", "BackgroundColor", c => c.String(maxLength: 100));
            AddColumn("dbo.NoteType", "FontColor", c => c.String(maxLength: 100));
            AddColumn("dbo.NoteType", "BorderColor", c => c.String(maxLength: 100));
            AddColumn("dbo.NoteType", "SendApprovalNotifications", c => c.Boolean(nullable: false));
            AddColumn("dbo.NoteType", "AutoWatchAuthors", c => c.Boolean(nullable: false));
            AddColumn("dbo.NoteType", "ApprovalUrlTemplate", c => c.String());
            CreateIndex("dbo.Note", "ParentNoteId");
            CreateIndex("dbo.Note", "EditedByPersonAliasId");
            AddForeignKey("dbo.Note", "EditedByPersonAliasId", "dbo.PersonAlias", "Id");
            AddForeignKey("dbo.Note", "ParentNoteId", "dbo.Note", "Id");

            // Update all current notes to Approved since approve is a new thing
            Sql("UPDATE [Note] SET [ApprovalStatus] = 1 WHERE [ApprovalStatus] != 1");

            // Fix any Notes that have still have caption of 'You - Personal Note' but have IsPrivateNote = false (this fixes an issue where Notes that were created as IsPrivate but changed to Not Private have the wrong caption)
            Sql(@"
UPDATE [Note]
SET [Caption] = ''
WHERE [Caption] = 'You - Personal Note'
	AND [IsPrivateNote] = 0
");

            // Add a Route and ApprovalUrlTemplate to Prayer Comment NoteType
            RockMigrationHelper.AddPageRoute(Rock.SystemGuid.Page.PRAYER_REQUEST_DETAIL, "PrayerRequestDetail/{PrayerRequestId}");

            Sql($@"
UPDATE [NoteType]
SET [ApprovalUrlTemplate] = '{{ ''Global'' | Attribute:''InternalApplicationRoot'' }}PrayerRequestDetail/{{ Note.EntityId }}#{{ Note.NoteAnchorId }}'
WHERE [Guid] = '{Rock.SystemGuid.NoteType.PRAYER_COMMENT}'");


            // Delete old NoteTypes block (it has been refactoed into NoteTypeList/NoteTypeDetail)
            RockMigrationHelper.DeleteBlock("F3805956-9A24-4FBF-8370-F3D29D788445");
            RockMigrationHelper.DeleteBlockType("44d2dab8-6dca-4dc3-b1ff-52da224b2d5c");

            // Migrate Pages/Blocks for Notes Updates
            MigrateNotesUpdatesBlocksAndPagesUp();

            // Create the Note Notifications and Approval System Email templates
            MigrateSystemEmailsUp();

            // Add Note Notifications Job
            // add ServiceJob: Send Note Notifications
            Sql(@"IF NOT EXISTS( SELECT [Id] FROM [ServiceJob] WHERE [Class] = 'Rock.Jobs.SendNoteNotifications' AND [Guid] = '3DB284D8-F8A9-4A49-959B-0629F9802CE0' )
            BEGIN
               INSERT INTO [ServiceJob] (
                  [IsSystem]
                  ,[IsActive]
                  ,[Name]
                  ,[Description]
                  ,[Class]
                  ,[CronExpression]
                  ,[NotificationStatus]
                  ,[Guid] )
               VALUES ( 
                  0
                  ,1
                  ,'Send Note Notifications'
                  ,'Send note watch and note approval notifications'
                  ,'Rock.Jobs.SendNoteNotifications'
                  ,'0 0 0/2 1/1 * ? *'
                  ,1
                  ,'3DB284D8-F8A9-4A49-959B-0629F9802CE0'
                  );
            END");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Model.ServiceJob", "08F3003B-F3E2-41EC-BDF1-A2B7AC2908CF", "Class", "Rock.Jobs.SendNoteNotifications", "Note Watch Notification Email", "", 1, @"21B92DE2-6825-45F3-BD27-43B47FE490D8", "CE0CE2F6-B3F1-4F4D-853B-FCFE51187328", "NoteWatchNotificationEmail");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Model.ServiceJob", "08F3003B-F3E2-41EC-BDF1-A2B7AC2908CF", "Class", "Rock.Jobs.SendNoteNotifications", "Note Approval Notification Email", "", 2, @"B2E3D75F-681E-430F-82C9-D0D681040FAF", "99FAB257-D55B-4432-9F4A-4449CDA75F83", "NoteApprovalNotificationEmail");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Model.ServiceJob", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "Class", "Rock.Jobs.SendNoteNotifications", "Cutoff Days", "Just in case the Note Notification service hasn't run for a while, this is the max number of days between the note edited date and the notification.", 3, @"7", "FA2BA8D9-F525-44B9-84B0-B63F9E3E04D3", "CutoffDays");
            RockMigrationHelper.AddAttributeValue("CE0CE2F6-B3F1-4F4D-853B-FCFE51187328", 37, @"21b92de2-6825-45f3-bd27-43b47fe490d8", "CE0CE2F6-B3F1-4F4D-853B-FCFE51187328"); // Send Note Notifications: Note Watch Notification Email
            RockMigrationHelper.AddAttributeValue("99FAB257-D55B-4432-9F4A-4449CDA75F83", 37, @"b2e3d75f-681e-430f-82c9-d0d681040faf", "99FAB257-D55B-4432-9F4A-4449CDA75F83"); // Send Note Notifications: Note Approval Notification Email
            RockMigrationHelper.AddAttributeValue("FA2BA8D9-F525-44B9-84B0-B63F9E3E04D3", 37, @"7", "FA2BA8D9-F525-44B9-84B0-B63F9E3E04D3");                                    // Send Note Notifications: Cutoff Days
        }
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            #region Photo Request Blocks

            // Add new PhotoOptOut block type
            RockMigrationHelper.UpdateBlockType("Photo Opt-Out", "Allows a person to opt-out of future photo requests.", "~/Blocks/Crm/PhotoRequest/PhotoOptOut.ascx", "CRM > PhotoRequest", "14293AEB-B0F5-434B-844A-66592AE3A416");

            // Add new VerifyPhoto block type 160DABF9-3549-447C-9E76-6CFCCCA481C0
            RockMigrationHelper.UpdateBlockType("Verify Photo", "Allows uploaded photos to be verified.", "~/Blocks/Crm/PhotoRequest/VerifyPhoto.ascx", "CRM > PhotoRequest", "160DABF9-3549-447C-9E76-6CFCCCA481C0");
            // Attrib for BlockType: VerifyPhoto:Photo Size
            RockMigrationHelper.AddBlockTypeAttribute("160DABF9-3549-447C-9E76-6CFCCCA481C0", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "Photo Size", "PhotoSize", "", "The size of the preview photo. Default is 65.", 0, @"True", "722F16A0-1F04-4D52-A850-A39055629617");

            // Replace the GroupMemberList block on the Verify Photo's page with the new, special VerifyPhoto block
            // - Remove Block: Group Member List, from Page: Verify Photos, Site: Rock RMS
            RockMigrationHelper.DeleteBlock("995E30ED-CB90-4A3F-B626-2C565BDB3FDE");
            // Add Block to Page: Verify Photos, Site: Rock RMS
            RockMigrationHelper.AddBlock("07E4BA19-614A-42D0-9D75-DFB31374844D", "", "160DABF9-3549-447C-9E76-6CFCCCA481C0", "Verify Photo Uploads", "Main", "", "", 0, "37BBE63E-5CB5-4F4D-8657-BBB13CA52919");

            // new Photo Request Opt Out page
            RockMigrationHelper.AddPage("EBAA5140-4B8F-44B8-B1E8-C73B654E4B22", "5FEAF34C-7FB6-4A11-8A1E-C452EC7849BD", "Photo Opt-Out", "Page where people can opt-out of future photo requests.", "04141667-1A08-4E15-8BB7-E3E312233E11", "");
            // Add Block to Page: PhotoOptOut, Site: Rock RMS
            RockMigrationHelper.AddBlock("04141667-1A08-4E15-8BB7-E3E312233E11", "", "14293AEB-B0F5-434B-844A-66592AE3A416", "Photo Opt-Out", "Main", "", "", 0, "44C793B7-8E2B-4D70-BFA1-5FE21FE4390C");

            // Add routes to new pages
            RockMigrationHelper.AddPageRoute("8559A9F1-C6A4-4945-B393-74F6706A8FA2", "PhotoRequest/Upload/{Person}");
            RockMigrationHelper.AddPageRoute("04141667-1A08-4E15-8BB7-E3E312233E11", "PhotoRequest/OptOut/{Person}");

            // Add new Photo Request Template communications template which uses the two new routes
            Sql(@"
            -- Add new Photo Request Template communications template
            DECLARE @EmailChannelId int = (SELECT [Id] FROM [EntityType] WHERE [Guid] = '5A653EBE-6803-44B4-85D2-FB7B8146D55D')

            DELETE [CommunicationTemplate] WHERE [Guid] = 'B9A0489C-A823-4C5C-A9F9-14A206EC3B88'

            INSERT [dbo].[CommunicationTemplate]
                ([Name]
                ,[Description]
                ,[Subject]
                ,[ChannelEntityTypeId]
                ,[ChannelDataJson]
                ,[CreatedDateTime]
                ,[ModifiedDateTime]
                ,[Guid] )
            VALUES
                (N'Photo Request Template'
                ,N'Includes the standard text and links for requesting a photo from a person.'
                ,N'Photo Request from {{ GlobalAttribute.OrganizationName }}'
                ,@EmailChannelId
                ,N'{ ""HtmlMessage"": ""{{ GlobalAttribute.EmailHeader }}\n<p>{{ Person.NickName }},</p>\n\n<p>We believe ministry is all about people and we find our ministry is much more personal when we have a recent photo of you in our membership system. Please take a minute to send us your photo using the button below - we&#39;d really appreciate it.</p>\n\n<p><a href=\""{{ GlobalAttribute.PublicApplicationRoot }}PhotoRequest/Upload/{{ Person.UrlEncodedKey }}\"">Upload Photo </a></p>\n\n<p>Your picture will remain confidential and will only be visible to staff and volunteers in a leadership position within {{ GlobalAttribute.OrganizationName }}.</p>\n\n<p><small>If you prefer never to receive these kinds of photo requests from us, please click this <a href=\""{{ GlobalAttribute.PublicApplicationRoot }}PhotoRequest/OptOut/{{ Person.UrlEncodedKey }}\"" style=\""line-height: 1.6em;\"">Opt Out</a>&nbsp;link.</small></p>\n\n<p>Thank you for helping us take our ministry to the next level,</p>\n\n<p>{{ Communication.ChannelData.FromName }}<br />\nEmail:&nbsp;<a href=\""mailto:{{ Communication.ChannelData.FromAddress }}\"" style=\""color: rgb(43, 166, 203); text-decoration: none;\"">{{ Communication.ChannelData.FromAddress }}</a></p>\n{{ GlobalAttribute.EmailFooter }}"" }'
                ,CAST(0x0000A37C01572215 AS DateTime)
                ,CAST(0x0000A38500F00EE8 AS DateTime)
                ,N'B9A0489C-A823-4C5C-A9F9-14A206EC3B88' )
");

            // Add new Action called "Request Photo" on person bio block
//            Sql( @"
//            -- Add new Action called 'Request Photo' on person bio block
//            DECLARE @BlockId int = ( SELECT [Id] FROM [Block] WHERE [Guid] = 'B5C1FDB6-0224-43E4-8E26-6B2EAF86253A' )
//            DECLARE @AttributeId int = ( SELECT [Id] FROM [Attribute] WHERE [Guid] = '35F69669-48DE-4182-B828-4EC9C1C31B08' )
//
//            IF NOT EXISTS (SELECT [ID] FROM  [AttributeValue] WHERE [AttributeId] = @AttributeId AND [EntityId] = @BlockId AND [Value] LIKE '%templateGuid=B9A0489C-A823-4C5C-A9F9-14A206EC3B88%' )
//            BEGIN
//                UPDATE [AttributeValue] SET [Value] = [Value] + '
//	                <li>
//		                <a href=''~/Communication/?templateGuid=B9A0489C-A823-4C5C-A9F9-14A206EC3B88&PersonId={0}'' tabindex=''0''>
//			                <i class=''fa fa-camera''></i>
//			                Request Photo
//		                </a>
//	                </li>'
//                WHERE [AttributeId] = @AttributeId
//                AND [EntityId] = @BlockId
//            END
//" );

            #endregion

            #region Add Test Gateway

            // Add the test gateway component and set attributes to make it active
            RockMigrationHelper.UpdateEntityType("Rock.Financial.TestGateway", "C22B0247-7C9F-411B-A1F5-0051FCBAC199", false, true);
            RockMigrationHelper.AddEntityAttribute("Rock.Financial.TestGateway", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "False", "5DBC1A27-6387-4248-B4A7-0292A4702556");
            RockMigrationHelper.AddAttributeValue("5DBC1A27-6387-4248-B4A7-0292A4702556", 0, "True", "4D0025EA-3A05-420D-8D37-2FAFD031C852");
            RockMigrationHelper.AddEntityAttribute("Rock.Financial.TestGateway", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "", "", "Order", "", "The order that this service should be used (priority)", 0, "", "693E05D8-0DE9-42E4-91E0-84ADAAFFCDEE");
            RockMigrationHelper.AddAttributeValue("693E05D8-0DE9-42E4-91E0-84ADAAFFCDEE", 0, "", "36E7A7C6-E985-48BB-8E66-A8393B9EA428");

            // Attrib for BlockType: Scheduled Transaction Edit:Credit Card Gateway
            RockMigrationHelper.UpdateBlockTypeAttribute("5171C4E5-7698-453E-9CC8-088D362296DE", "A7486B0E-4CA2-4E00-A987-5544C7DABA76", "Credit Card Gateway", "CCGateway", "", "The payment gateway to use for Credit Card transactions", 0, @"C22B0247-7C9F-411B-A1F5-0051FCBAC199", "8177CE07-AA1B-43F4-ABCE-23E63DA8EBC8");
            RockMigrationHelper.AddBlockAttributeValue("CC4AC47D-1EA8-406F-94D5-50D19DC6B87A", "8177CE07-AA1B-43F4-ABCE-23E63DA8EBC8", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("6BF2F96A-51D6-4A84-BDA4-4EE6FDC2B515", "8177CE07-AA1B-43F4-ABCE-23E63DA8EBC8", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("75F15397-3B82-4879-B069-DABD3619FAA3", "8177CE07-AA1B-43F4-ABCE-23E63DA8EBC8", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");

            // Attrib for BlockType: Scheduled Transaction Edit:ACH Gateway
            RockMigrationHelper.UpdateBlockTypeAttribute("5171C4E5-7698-453E-9CC8-088D362296DE", "A7486B0E-4CA2-4E00-A987-5544C7DABA76", "ACH Gateway", "ACHGateway", "", "The payment gateway to use for ACH (bank account) transactions", 1, @"C22B0247-7C9F-411B-A1F5-0051FCBAC199", "FC9DF232-D7B1-4CA9-B348-D139276783BB");
            RockMigrationHelper.AddBlockAttributeValue("CC4AC47D-1EA8-406F-94D5-50D19DC6B87A", "FC9DF232-D7B1-4CA9-B348-D139276783BB", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("6BF2F96A-51D6-4A84-BDA4-4EE6FDC2B515", "FC9DF232-D7B1-4CA9-B348-D139276783BB", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("75F15397-3B82-4879-B069-DABD3619FAA3", "FC9DF232-D7B1-4CA9-B348-D139276783BB", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");

            // Attrib for BlockType: Transaction Entry:Credit Card Gateway
            RockMigrationHelper.UpdateBlockTypeAttribute("74EE3481-3E5A-4971-A02E-D463ABB45591", "A7486B0E-4CA2-4E00-A987-5544C7DABA76", "Credit Card Gateway", "CCGateway", "", "The payment gateway to use for Credit Card transactions", 0, @"C22B0247-7C9F-411B-A1F5-0051FCBAC199", "3D478949-1F85-4E81-A403-22BBA96B8F69");
            RockMigrationHelper.AddBlockAttributeValue("20C12A0F-BEC1-4620-9273-EEFE4CFB1D96", "3D478949-1F85-4E81-A403-22BBA96B8F69", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("8ADB1C1F-299B-461A-8469-0FF4E2C98216", "3D478949-1F85-4E81-A403-22BBA96B8F69", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");

            // Attrib for BlockType: Transaction Entry:ACH Gateway
            RockMigrationHelper.UpdateBlockTypeAttribute("74EE3481-3E5A-4971-A02E-D463ABB45591", "A7486B0E-4CA2-4E00-A987-5544C7DABA76", "ACH Gateway", "ACHGateway", "", "The payment gateway to use for ACH (bank account) transactions", 1, @"C22B0247-7C9F-411B-A1F5-0051FCBAC199", "D6429E78-E8F0-4EF2-9D18-DFDDE4ECC6A7");
            RockMigrationHelper.AddBlockAttributeValue("20C12A0F-BEC1-4620-9273-EEFE4CFB1D96", "D6429E78-E8F0-4EF2-9D18-DFDDE4ECC6A7", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");
            RockMigrationHelper.AddBlockAttributeValue("8ADB1C1F-299B-461A-8469-0FF4E2C98216", "D6429E78-E8F0-4EF2-9D18-DFDDE4ECC6A7", "C22B0247-7C9F-411B-A1F5-0051FCBAC199");

            #endregion

            #region Financial Source Defined Values

            // Update the values for transaction source
            Sql(@"
    DECLARE @MailerId int = ( SELECT TOP 1 [Id] FROM [DefinedValue] WHERE [Guid] = '0149EB64-00C4-4C69-B1A6-2FD0EDFC6ACB' )
    DECLARE @WebsiteId int = ( SELECT TOP 1 [Id] FROM [DefinedValue] WHERE [Guid] = '7D705CE7-7B11-4342-A58E-53617C5B4E69' )
    UPDATE [FinancialTransaction] SET [SourceTypeValueId] = @WebsiteId WHERE [SourceTypeValueId] = @MailerId
");
            RockMigrationHelper.DeleteDefinedValue("0149EB64-00C4-4C69-B1A6-2FD0EDFC6ACB");    // Delete 'Mailer'
            RockMigrationHelper.UpdateDefinedValue_pre20140819("4F02B41E-AB7D-4345-8A97-3904DDD89B01", "Website", "Transactions that originated from the website", "7D705CE7-7B11-4342-A58E-53617C5B4E69", true);
            RockMigrationHelper.UpdateDefinedValue_pre20140819("4F02B41E-AB7D-4345-8A97-3904DDD89B01", "Kiosk", "Transactions that originated from a kiosk", "260EEA80-821A-4F79-973F-49DF79C955F7", false);
            RockMigrationHelper.UpdateDefinedValue_pre20140819("4F02B41E-AB7D-4345-8A97-3904DDD89B01", "Mobile Application", "Transactions that originated from a mobile application", "8ADCEC72-63FC-4F08-A4CC-72BCE470172C", false);
            RockMigrationHelper.UpdateDefinedValue_pre20140819("4F02B41E-AB7D-4345-8A97-3904DDD89B01", "On-Site Collection", "Transactions that were collected on-site", "BE7ECF50-52BC-4774-808D-574BA842DB98", false);

            // Set default source to website on Financial Entry block
            RockMigrationHelper.AddBlockAttributeValue("8ADB1C1F-299B-461A-8469-0FF4E2C98216", "5C54E6E7-1C21-4959-98EA-FB1C2D0A0D61", @"7D705CE7-7B11-4342-A58E-53617C5B4E69");
            RockMigrationHelper.AddBlockAttributeValue("20C12A0F-BEC1-4620-9273-EEFE4CFB1D96", "5C54E6E7-1C21-4959-98EA-FB1C2D0A0D61", @"7D705CE7-7B11-4342-A58E-53617C5B4E69");

            #endregion

            #region Deceased DataView Filter

            Sql(@"
    -- Add a filter to base dataview to exclude deceased people
    DECLARE @ParentDataViewFilterId INT = ( SELECT TOP 1 [DataViewFilterId] FROM [DataView] WHERE [Guid] = '0DA5F82F-CFFE-45AF-B725-49B3899A1F72' )
    DECLARE @PropertyFilterEntityTypeId INT = ( SELECT TOP 1 [Id] FROM [EntityType] WHERE [Guid] = '03F0D6AC-D181-48B6-B4BC-1F2652B55323' )
    INSERT INTO [DataViewFilter] ( [ExpressionType], [ParentId], [EntityTypeId], [Selection], [Guid] )
    VALUES ( 0, @ParentDataViewFilterId, @PropertyFilterEntityTypeId ,N'[
  ""IsDeceased"",
  ""False""
]'
    ,'53B219C5-A25D-42C3-9345-DFDFF6331CF1' )
");

            #endregion

            #region Misc Changes

            // set security for View My Giving page (VIEW: auth users = true, all users = false)
            RockMigrationHelper.AddSecurityAuthForPage("621e03c5-6586-450b-a340-cc7d9727b69a", 0, "View", true, null, 2, "f328528c-e874-415a-9319-70783dcd6841");
            RockMigrationHelper.AddSecurityAuthForPage("621e03c5-6586-450b-a340-cc7d9727b69a", 0, "View", false, null, 1, "0a451fc6-72ef-4daf-a251-beada05b360a");

            // set security for Manage Giving Profile page (VIEW: auth users = true, all users = false)
            RockMigrationHelper.AddSecurityAuthForPage("fffdce23-7b67-4b0d-8da0-e44d883708cc", 0, "View", true, null, 2, "6189ac92-8a2c-4019-b44e-3433370f5eea");
            RockMigrationHelper.AddSecurityAuthForPage("fffdce23-7b67-4b0d-8da0-e44d883708cc", 0, "View", false, null, 1, "de61aff2-e2a8-4922-a665-4e866685f5d0");

            // set security for Edit Giving Profile page (VIEW: auth users = true, all users = false)
            RockMigrationHelper.AddSecurityAuthForPage("2072f4bc-53b4-4481-bc15-38f14425c6c9", 0, "View", true, null, 2, "e9865cc7-4aa5-4564-98b5-02e447700de0");
            RockMigrationHelper.AddSecurityAuthForPage("2072f4bc-53b4-4481-bc15-38f14425c6c9", 0, "View", false, null, 1, "de3f1cce-d9f0-4df8-b4c3-75055f9bf526");

            Sql(@"
    --make content blocks on intranet pages non system    
    UPDATE [Block]
    SET [IsSystem] = 0
    WHERE [Guid] IN ( 'b8224c72-4168-40f0-96be-38f2afd525f5', '718c516f-0a1d-4dbc-a939-1d9777208fec')

    -- rename the inactive report to 'self inactivated individuals' this is closer to what it really is
    UPDATE [Report] 
    SET [Name] = 'Self Inactivated Individuals', [IsSystem] = 0
    WHERE [Guid] = '87d3e118-ada8-4424-b63b-9482a7d9e609'

    -- set display setting so pages show in nav with new permissions
    UPDATE [Page]
    SET [DisplayInNavWhen] = 1
    WHERE [Guid] IN ('fffdce23-7b67-4b0d-8da0-e44d883708cc','621e03c5-6586-450b-a340-cc7d9727b69a')
");

            #endregion
        }
        /// <summary>
        /// Operations to be performed during the upgrade process.
        /// </summary>
        public override void Up()
        {
            CreateTable(
                "dbo.MergeTemplate",
                c => new
            {
                Id                            = c.Int(nullable: false, identity: true),
                Name                          = c.String(nullable: false, maxLength: 100),
                Description                   = c.String(),
                TemplateBinaryFileId          = c.Int(nullable: false),
                MergeTemplateTypeEntityTypeId = c.Int(nullable: false),
                CategoryId                    = c.Int(nullable: false),
                PersonAliasId                 = c.Int(),
                CreatedDateTime               = c.DateTime(),
                ModifiedDateTime              = c.DateTime(),
                CreatedByPersonAliasId        = c.Int(),
                ModifiedByPersonAliasId       = c.Int(),
                Guid                          = c.Guid(nullable: false),
                ForeignId                     = c.String(maxLength: 50),
            })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Category", t => t.CategoryId)
            .ForeignKey("dbo.PersonAlias", t => t.CreatedByPersonAliasId)
            .ForeignKey("dbo.EntityType", t => t.MergeTemplateTypeEntityTypeId)
            .ForeignKey("dbo.PersonAlias", t => t.ModifiedByPersonAliasId)
            .ForeignKey("dbo.PersonAlias", t => t.PersonAliasId)
            .ForeignKey("dbo.BinaryFile", t => t.TemplateBinaryFileId)
            .Index(t => t.TemplateBinaryFileId)
            .Index(t => t.MergeTemplateTypeEntityTypeId)
            .Index(t => t.CategoryId)
            .Index(t => t.PersonAliasId)
            .Index(t => t.CreatedByPersonAliasId)
            .Index(t => t.ModifiedByPersonAliasId)
            .Index(t => t.Guid, unique: true);

            AddColumn("dbo.EntitySetItem", "AdditionalMergeValuesJson", c => c.String());

            RockMigrationHelper.UpdateBinaryFileType(Rock.SystemGuid.EntityType.STORAGE_PROVIDER_DATABASE, "Merge Template", "Usually either a MS Word Docx or Html file", "fa fa-files-o", Rock.SystemGuid.BinaryFiletype.MERGE_TEMPLATE, false, true);
            RockMigrationHelper.AddSecurityAuthForBinaryFileType(Rock.SystemGuid.BinaryFiletype.MERGE_TEMPLATE, 0, "Edit", true, Rock.SystemGuid.Group.GROUP_ADMINISTRATORS, Model.SpecialRole.None, "D5D0FB59-993D-4B70-851C-18787AE8DE09");
            RockMigrationHelper.AddSecurityAuthForBinaryFileType(Rock.SystemGuid.BinaryFiletype.MERGE_TEMPLATE, 1, "Edit", true, Rock.SystemGuid.Group.GROUP_STAFF_MEMBERS, Model.SpecialRole.None, "00615556-29EB-4085-A774-F1D203ECE9D0");
            RockMigrationHelper.AddSecurityAuthForBinaryFileType(Rock.SystemGuid.BinaryFiletype.MERGE_TEMPLATE, 2, "Edit", true, Rock.SystemGuid.Group.GROUP_STAFF_LIKE_MEMBERS, Model.SpecialRole.None, "E7300CED-B48F-4803-B27C-8851B2905668");

            RockMigrationHelper.UpdateEntityType("Rock.MergeTemplates.HtmlMergeTemplateType", "Html", "Rock.MergeTemplates.HtmlMergeTemplateType, Rock, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null", false, true, "5fbff041-9edc-41a3-8a92-d7ac4ff88221");
            RockMigrationHelper.UpdateEntityType("Rock.MergeTemplates.WordDocumentMergeTemplateType", "Word Document", "Rock.MergeTemplates.WordDocumentMergeTemplateType, Rock, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null", false, true, "7b86e093-3eb8-46ca-8ca7-068d699e7811");

            RockMigrationHelper.UpdateEntityType("Rock.Model.MergeTemplate", "Merge Template", "Rock.Model.MergeTemplate, Rock, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null", true, true, Rock.SystemGuid.EntityType.MERGE_TEMPLATE);

            RockMigrationHelper.AddEntityAttribute("Rock.MergeTemplates.HtmlMergeTemplateType", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "E4A988D8-181A-417B-B13C-4FD69093D687");
            RockMigrationHelper.AddAttributeValue("E4A988D8-181A-417B-B13C-4FD69093D687", 0, "True", "CB5374AA-5BEF-4FA1-9801-128A4ADC3BF1");

            RockMigrationHelper.AddEntityAttribute("Rock.MergeTemplates.WordDocumentMergeTemplateType", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "", "Should Service be used?", 0, "True", "5515CA06-7FA3-4D63-A3CF-B0AE9108CF33");
            RockMigrationHelper.AddAttributeValue("5515CA06-7FA3-4D63-A3CF-B0AE9108CF33", 0, "True", "A6F63120-4120-4116-9E4D-D82302A753D5");

            RockMigrationHelper.UpdateCategory(Rock.SystemGuid.EntityType.MERGE_TEMPLATE, "Personal", "fa fa-user", "Personal Merge Templates", Rock.SystemGuid.Category.PERSONAL_MERGE_TEMPLATE, int.MaxValue);

            Sql(@"/*
<doc>
	<summary>
        This function returns either the FullName of the specified Person or a list of names of family members
        In the case of a group (family), it will return the names of the adults of the family. If there are no adults in the family, the names of the non-adults will be listed
        Example1 (specific person): Bob Smith 
        Example2 (family with kids): Bill and Sally Jones
        Example3 (different lastnames): Jim Jackson and Betty Sanders
        Example4 (just kids): Joey, George, and Jenny Swenson
	</summary>

	<returns>
		* Name(s)
	</returns>
    <param name='PersonId' datatype='int'>The Person to get a full name for. NULL means use the GroupId paramter </param>
	<param name='@GroupId' datatype='int'>The Group (family) to get the list of names for</param>
	<remarks>
		[ufnCrm_GetFamilyTitle] is used by spFinance_ContributionStatementQuery as part of generating Contribution Statements
	</remarks>
	<code>
		SELECT * FROM [dbo].[ufnCrm_GetFamilyTitle](2, null, default) -- Single Person
        SELECT * FROM [dbo].[ufnCrm_GetFamilyTitle](null, 44, default) -- Family
        SELECT * FROM [dbo].[ufnCrm_GetFamilyTitle](null, 44, '2,3') -- Family, limited to the specified PersonIds
	</code>
</doc>
*/
ALTER FUNCTION [dbo].[ufnCrm_GetFamilyTitle] (
    @PersonId INT
    ,@GroupId INT
    ,@GroupPersonIds VARCHAR(max) = NULL
    ,@UseNickName BIT = 0
    )
RETURNS @PersonNamesTable TABLE (PersonNames VARCHAR(max))
AS
BEGIN
    DECLARE @PersonNames VARCHAR(max);
    DECLARE @AdultLastNameCount INT;
    DECLARE @GroupFirstOrNickNames VARCHAR(max) = '';
    DECLARE @GroupLastName VARCHAR(max);
    DECLARE @GroupAdultFullNames VARCHAR(max) = '';
    DECLARE @GroupNonAdultFullNames VARCHAR(max) = '';
    DECLARE @GroupMemberTable TABLE (
        LastName VARCHAR(max)
        ,FirstOrNickName VARCHAR(max)
        ,FullName VARCHAR(max)
        ,Gender INT
        ,GroupRoleGuid UNIQUEIDENTIFIER
        );
    DECLARE @cGROUPTYPEROLE_FAMILY_MEMBER_ADULT UNIQUEIDENTIFIER = '2639F9A5-2AAE-4E48-A8C3-4FFE86681E42';

    IF (@PersonId IS NOT NULL)
    BEGIN
        -- just getting the Person Names portion of the address for an individual person
        SELECT @PersonNames = CASE @UseNickName
                WHEN 1
                    THEN ISNULL([p].[NickName], '')
                ELSE ISNULL([p].[FirstName], '')
                END + ' ' + ISNULL([p].[LastName], '') + ' ' + ISNULL([dv].[Value], '')
        FROM [Person] [p]
        LEFT OUTER JOIN [DefinedValue] [dv] ON [dv].[Id] = [p].[SuffixValueId]
        WHERE [p].[Id] = @PersonId;
    END
    ELSE
    BEGIN
        -- populate a table variable with the data we'll need for the different cases
        -- if GroupPersonIds is set (comma-delimited) only a subset of the family members should be combined
        INSERT INTO @GroupMemberTable
        SELECT [p].[LastName]
            ,CASE @UseNickName
                WHEN 1
                    THEN ISNULL([p].[NickName], '')
                ELSE ISNULL([p].[FirstName], '')
                END [FirstName]
            ,CASE @UseNickName
                WHEN 1
                    THEN ISNULL([p].[NickName], '')
                ELSE ISNULL([p].[FirstName], '')
                END + ' ' + ISNULL([p].[LastName], '') + ' ' + ISNULL([dv].[Value], '') [FullName]
            ,[p].Gender
            ,[gr].[Guid]
        FROM [GroupMember] [gm]
        JOIN [Person] [p] ON [p].[Id] = [gm].[PersonId]
        LEFT OUTER JOIN [DefinedValue] [dv] ON [dv].[Id] = [p].[SuffixValueId]
        JOIN [GroupTypeRole] [gr] ON [gm].[GroupRoleId] = [gr].[Id]
        WHERE [GroupId] = @GroupId
            AND (
                ISNULL(@GroupPersonIds, '') = ''
                OR (
                    p.[Id] IN (
                        SELECT *
                        FROM ufnUtility_CsvToTable(@GroupPersonIds)
                        )
                    )
                )

        -- determine adultCount and if we can use the same lastname for all adults, and get lastname while we are at it
        SELECT @AdultLastNameCount = count(DISTINCT [LastName])
            ,@GroupLastName = max([LastName])
        FROM @GroupMemberTable
        WHERE [GroupRoleGuid] = @cGROUPTYPEROLE_FAMILY_MEMBER_ADULT;

        IF @AdultLastNameCount > 0
        BEGIN
            -- get the FirstNames and Adult FullNames for use in the cases of families with Adults
            SELECT @GroupFirstOrNickNames = @GroupFirstOrNickNames + [FirstOrNickName] + ' & '
                ,@GroupAdultFullNames = @GroupAdultFullNames + [FullName] + ' & '
            FROM @GroupMemberTable g
            WHERE g.[GroupRoleGuid] = @cGROUPTYPEROLE_FAMILY_MEMBER_ADULT
            ORDER BY g.Gender
                ,g.FirstOrNickName

            -- cleanup the trailing ' &'s
            IF len(@GroupFirstOrNickNames) > 2
            BEGIN
                -- trim the extra ' &' off the end 
                SET @GroupFirstOrNickNames = SUBSTRING(@GroupFirstOrNickNames, 0, len(@GroupFirstOrNickNames) - 1)
            END

            IF len(@GroupAdultFullNames) > 2
            BEGIN
                -- trim the extra ' &' off the end 
                SET @GroupAdultFullNames = SUBSTRING(@GroupAdultFullNames, 0, len(@GroupAdultFullNames) - 1)
            END
        END

        IF @AdultLastNameCount = 0
        BEGIN
            -- get the NonAdultFullNames for use in the case of families without adults 
            SELECT @GroupNonAdultFullNames = @groupNonAdultFullNames + [FullName] + ' & '
            FROM @GroupMemberTable
            ORDER BY [FullName]

            IF len(@GroupNonAdultFullNames) > 2
            BEGIN
                -- trim the extra ' &' off the end 
                SET @GroupNonAdultFullNames = SUBSTRING(@GroupNonAdultFullNames, 0, len(@GroupNonAdultFullNames) - 1)
            END
        END

        IF (@AdultLastNameCount = 1)
        BEGIN
            -- just one lastname and at least one adult. Get the Person Names portion of the address in the format <MaleAdult> & <FemaleAdult> <LastName>
            SET @PersonNames = @GroupFirstOrNickNames + ' ' + @GroupLastName;
        END
        ELSE IF (@AdultLastNameCount = 0)
        BEGIN
            -- no adults in family, list all members of the family in 'Fullname & FullName & ...' format
            SET @PersonNames = @GroupNonAdultFullNames;
        END
        ELSE
        BEGIN
            -- multiple adult lastnames
            SET @PersonNames = @GroupAdultFullNames;
        END
    END

    INSERT INTO @PersonNamesTable ([PersonNames])
    VALUES (@PersonNames);

    RETURN
END
");

            Sql(@"/*
<doc>
	<summary>
		This stored procedure returns the Mailing Addresses and any CustomMessages for the Contribution Statement, but not the actual transactions
		The StatementGenerator utility uses this procedure along with querying transactions thru REST to generate statements
	</summary>

	<returns>
		* PersonId
		* GroupId
		* AddressPersonNames
		* Street1
		* Street2
		* City
		* State
		* PostalCode
		* StartDate
		* EndDate
		* CustomMessage1
		* CustomMessage2
	</returns>
	<param name='StartDate' datatype='datetime'>The starting date of the date range</param>
	<param name='EndDate' datatype='datetime'>The ending date of the date range</param>
	<param name='AccountIds' datatype='varchar(max)'>Comma delimited list of account ids. NULL means all</param>
	<param name='PersonId' datatype='int'>Person the statement if for. NULL means all persons that have transactions for the date range</param>
	<param name='OrderByPostalCode' datatype='int'>Set to 1 to have the results sorted by PostalCode, 0 for no particular order</param>
	<remarks>	
		Uses the following constants:
			* Group Type - Family: 790E3215-3B10-442B-AF69-616C0DCB998E
			* Group Role - Adult: 2639F9A5-2AAE-4E48-A8C3-4FFE86681E42
			* Group Role - Child: C8B1814F-6AA7-4055-B2D7-48FE20429CB9
	</remarks>
	<code>
		EXEC [dbo].[spFinance_ContributionStatementQuery] '01-01-2014', '01-01-2015', null, null, 0, 1 -- year 2014 statements for all persons that have a mailing address
        EXEC [dbo].[spFinance_ContributionStatementQuery] '01-01-2014', '01-01-2015', null, null, 1, 1 -- year 2014 statements for all persons regardless of mailing address
        EXEC [dbo].[spFinance_ContributionStatementQuery] '01-01-2014', '01-01-2015', null, 2, 1, 1  -- year 2014 statements for Ted Decker
	</code>
</doc>
*/
ALTER PROCEDURE [dbo].[spFinance_ContributionStatementQuery]
	@StartDate datetime
	, @EndDate datetime
	, @AccountIds varchar(max) 
	, @PersonId int -- NULL means all persons
    , @IncludeIndividualsWithNoAddress bit 
	, @OrderByPostalCode bit
AS
BEGIN
	DECLARE @cGROUPTYPE_FAMILY uniqueidentifier = '790E3215-3B10-442B-AF69-616C0DCB998E'	
	DECLARE @cLOCATION_TYPE_HOME uniqueidentifier = '8C52E53C-2A66-435A-AE6E-5EE307D9A0DC'

	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

	;WITH tranListCTE
	AS
	(
		SELECT  
			[pa].[PersonId] 
		FROM 
			[FinancialTransaction] [ft]
		INNER JOIN 
			[FinancialTransactionDetail] [ftd] ON [ft].[Id] = [ftd].[TransactionId]
		INNER JOIN 
			[PersonAlias] [pa] ON [pa].[id] = [ft].[AuthorizedPersonAliasId]
		WHERE 
			([TransactionDateTime] >= @StartDate and [TransactionDateTime] < @EndDate)
		AND 
			(
				(@AccountIds is null)
				OR
				(ftd.[AccountId] in (select * from ufnUtility_CsvToTable(@AccountIds)))
			)
	)

	SELECT * FROM (
    SELECT 
		  [pg].[PersonId]
		, [pg].[GroupId]
		, [pn].[PersonNames] [AddressPersonNames]
        , case when l.Id is null then 0 else 1 end [HasAddress]
		, [l].[Street1]
		, [l].[Street2]
		, [l].[City]
		, [l].[State]
		, [l].[PostalCode]
		, @StartDate [StartDate]
		, @EndDate [EndDate]
		, null [CustomMessage1]
		, null [CustomMessage2]
	FROM (
		-- Get distinct Giving Groups for Persons that have a specific GivingGroupId and have transactions that match the filter
		-- These are Persons that give as part of a Group.  For example, Husband and Wife
		SELECT DISTINCT
			null [PersonId] 
			, [g].[Id] [GroupId]
		FROM 
			[Person] [p]
		INNER JOIN 
			[Group] [g] ON [p].[GivingGroupId] = [g].[Id]
		WHERE 
		(
			(@personId is null) 
		OR 
			([p].[Id] = @personId)
		)
        AND
			[p].[Id] in (SELECT * FROM tranListCTE)
		UNION
		-- Get Persons and their GroupId(s) that do not have GivingGroupId and have transactions that match the filter.        
		-- These are the persons that give as individuals vs as part of a group. We need the Groups (families they belong to) in order 
		-- to determine which address(es) the statements need to be mailed to 
		SELECT  
			[p].[Id] [PersonId],
			[g].[Id] [GroupId]
		FROM
			[Person] [p]
		JOIN 
			[GroupMember] [gm]
		ON 
			[gm].[PersonId] = [p].[Id]
		JOIN 
			[Group] [g]
		ON 
			[gm].[GroupId] = [g].[Id]
		WHERE
			[p].[GivingGroupId] is null
		AND
			[g].[GroupTypeId] = (SELECT Id FROM GroupType WHERE [Guid] = @cGROUPTYPE_FAMILY)
        AND
		(
			(@personId is null) 
		OR 
			([p].[Id] = @personId)
		)
		AND [p].[Id] IN (SELECT * FROM tranListCTE)
	) [pg]
	CROSS APPLY 
		[ufnCrm_GetFamilyTitle]([pg].[PersonId], [pg].[GroupId], default, default) [pn]
	LEFT OUTER JOIN (
    SELECT l.*, gl.GroupId from
		[GroupLocation] [gl] 
	LEFT OUTER JOIN
		[Location] [l]
	ON 
		[l].[Id] = [gl].[LocationId]
	WHERE 
		[gl].[IsMailingLocation] = 1
	AND
		[gl].[GroupLocationTypeValueId] = (SELECT Id FROM DefinedValue WHERE [Guid] = @cLOCATION_TYPE_HOME)
        ) [l] 
        ON 
		[l].[GroupId] = [pg].[GroupId]
    ) n
    WHERE n.HasAddress = 1 or @IncludeIndividualsWithNoAddress = 1
    ORDER BY
	CASE WHEN @OrderByPostalCode = 1 THEN PostalCode END
    
END
");

            RockMigrationHelper.AddPage("0B213645-FA4E-44A5-8E4C-B2D8EF054985", "0CB60906-6B74-44FD-AB25-026050EF70EB", "Merge Templates", "", "679AF013-0093-435E-AA49-E73B99EB9710", "fa fa-files-o");      // Site:Rock RMS
            RockMigrationHelper.AddPage("C831428A-6ACD-4D49-9B2D-046D399E3123", "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Merge Template Types", "", "42717D07-3744-4187-89EC-F01EDD0FF5AD", "fa fa-files-o"); // Site:Rock RMS
            RockMigrationHelper.AddPage("936C90C4-29CF-4665-A489-7C687217F7B8", "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Merge Template Entry", "", "B864FBFD-3699-4DB5-A8A9-12B2FEA86C7A", "");              // Site:Rock RMS

            RockMigrationHelper.AddPageRoute("B864FBFD-3699-4DB5-A8A9-12B2FEA86C7A", "MergeTemplate/{Set}");
            RockMigrationHelper.UpdateBlockType("Merge Template Detail", "Block for administrating a Merge Template", "~/Blocks/Core/MergeTemplateDetail.ascx", "Core", "820DE5F9-8391-4A2A-AA87-24156882BD5F");
            RockMigrationHelper.UpdateBlockType("Merge Template Entry", "Used for merging data into output documents, such as Word, Html, using a pre-defined template.", "~/Blocks/Core/MergeTemplateEntry.ascx", "Core", "8C6280DA-9BB4-47C8-96BA-3878B8B85466");
            RockMigrationHelper.UpdateBlockType("Person Update - Kiosk", "Block used to update a person's information from a kiosk.", "~/Blocks/Crm/PersonUpdate.Kiosk.ascx", "CRM", "61C5C8F2-6F76-4583-AB97-228878A6AB65");
            // Add Block to Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlock("679AF013-0093-435E-AA49-E73B99EB9710", "", "ADE003C7-649B-466A-872B-B8AC952E7841", "Merge Template Category Tree View", "Sidebar1", "", "", 0, "2F302012-6DEC-4963-B519-F8567CBAE67B");

            // Add Block to Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlock("679AF013-0093-435E-AA49-E73B99EB9710", "", "7BC54887-21C2-4688-BD1D-C1C8B9C86F7C", "Merge Template Category Detail", "Main", "", "", 0, "EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37");

            // Add Block to Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlock("679AF013-0093-435E-AA49-E73B99EB9710", "", "820DE5F9-8391-4A2A-AA87-24156882BD5F", "Merge Template Detail", "Main", "", "", 1, "72291AAD-E4B8-47CB-AA8E-28FFA2243FF5");

            // Add Block to Page: Merge Template Types, Site: Rock RMS
            RockMigrationHelper.AddBlock("42717D07-3744-4187-89EC-F01EDD0FF5AD", "", "21F5F466-59BC-40B2-8D73-7314D936C3CB", "Merge Template Types", "Main", "", "", 0, "4120986C-B653-4C10-B54F-542A3168D211");

            // Add Block to Page: Merge Template Entry, Site: Rock RMS
            RockMigrationHelper.AddBlock("B864FBFD-3699-4DB5-A8A9-12B2FEA86C7A", "", "8C6280DA-9BB4-47C8-96BA-3878B8B85466", "Merge Template Entry", "Main", "", "", 0, "3CF8137C-23C8-472A-936A-EF8086ACB65C");

            // Attrib for BlockType: Category Tree View:Exclude Categories
            RockMigrationHelper.AddBlockTypeAttribute("ADE003C7-649B-466A-872B-B8AC952E7841", "775899FB-AC17-4C2C-B809-CF3A1D2AA4E1", "Exclude Categories", "ExcludeCategories", "", "Select any category that you need to exclude from the tree view", 0, @"", "61398707-FCCE-4AFD-8374-110BCA275F34");

            // Attrib for BlockType: Category Tree View:Root Category
            RockMigrationHelper.AddBlockTypeAttribute("ADE003C7-649B-466A-872B-B8AC952E7841", "309460EF-0CC5-41C6-9161-B3837BA3D374", "Root Category", "RootCategory", "", "Select the root category to use as a starting point for the tree view.", 0, @"", "2080E00B-63E4-4874-B06A-ADE1B4F3B3AD");

            // Attrib for BlockType: Merge Template Detail:Merge Templates Ownership
            RockMigrationHelper.AddBlockTypeAttribute("820DE5F9-8391-4A2A-AA87-24156882BD5F", "7525C4CB-EE6B-41D4-9B64-A08048D5A5C0", "Merge Templates Ownership", "MergeTemplatesOwnership", "", "Set this to restrict if the merge template must be a Personal or Global merge template.", 0, @"Global", "97860FA4-F59F-473D-A456-550FA40B937C");

            // Attrib for BlockType: Category Detail:Exclude Categories
            RockMigrationHelper.AddBlockTypeAttribute("7BC54887-21C2-4688-BD1D-C1C8B9C86F7C", "775899FB-AC17-4C2C-B809-CF3A1D2AA4E1", "Exclude Categories", "ExcludeCategories", "", "Select any category that you need to exclude from the parent category picker", 0, @"", "AB542995-876F-4B8F-8417-11D83369289E");

            // Attrib for BlockType: Category Detail:Root Category
            RockMigrationHelper.AddBlockTypeAttribute("7BC54887-21C2-4688-BD1D-C1C8B9C86F7C", "309460EF-0CC5-41C6-9161-B3837BA3D374", "Root Category", "RootCategory", "", "Select the root category to use as a starting point for the parent category picker.", 0, @"", "C3B72ADF-93D7-42CF-A103-8A7661A6926B");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Entity Type Friendly Name Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "07213E2C-C239-47CA-A781-F7A908756DC2", @"");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Show Unnamed Entity Items Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "C48600CD-2C65-46EF-84E8-975F0DE8C28E", @"True");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Exclude Categories Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "61398707-FCCE-4AFD-8374-110BCA275F34", @"a9f2f544-660b-4176-acad-88898416a66e");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Root Category Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "2080E00B-63E4-4874-B06A-ADE1B4F3B3AD", @"");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Entity Type Qualifier Property Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "2D5FF74A-D316-4924-BCD2-6AA338D8DAAC", @"");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Entity type Qualifier Value Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "F76C5EEF-FD45-4BD6-A903-ED5AB53BB928", @"");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Page Parameter Key Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "AA057D3E-00CC-42BD-9998-600873356EDB", @"MergeTemplateId");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Entity Type Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "06D414F0-AA20-4D3C-B297-1530CCD64395", @"cd1db988-6891-4b0f-8d1b-b0a311a3bc3e");

            // Attrib Value for Block:Merge Template Category Tree View, Attribute:Detail Page Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("2F302012-6DEC-4963-B519-F8567CBAE67B", "AEE521D8-124D-4BB3-8A80-5F368E5CEC15", @"679af013-0093-435e-aa49-e73b99eb9710");

            // Attrib Value for Block:Merge Template Category Detail, Attribute:Exclude Categories Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37", "AB542995-876F-4B8F-8417-11D83369289E", @"a9f2f544-660b-4176-acad-88898416a66e");

            // Attrib Value for Block:Merge Template Category Detail, Attribute:Root Category Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37", "C3B72ADF-93D7-42CF-A103-8A7661A6926B", @"");

            // Attrib Value for Block:Merge Template Category Detail, Attribute:Entity Type Qualifier Property Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37", "620957FF-BC28-4A89-A74F-C917DA5CFD47", @"");

            // Attrib Value for Block:Merge Template Category Detail, Attribute:Entity Type Qualifier Value Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37", "985128EE-D40C-4598-B14B-7AD728ECCE38", @"");

            // Attrib Value for Block:Merge Template Category Detail, Attribute:Entity Type Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("EC3C1F43-260F-44DC-B0FC-9C6CA9F64F37", "FF3A33CF-8897-4FC6-9C16-64FA25E6C297", @"cd1db988-6891-4b0f-8d1b-b0a311a3bc3e");

            // Attrib Value for Block:Merge Template Detail, Attribute:Merge Templates Ownership Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("72291AAD-E4B8-47CB-AA8E-28FFA2243FF5", "97860FA4-F59F-473D-A456-550FA40B937C", @"0");

            // Attrib Value for Block:Merge Template Types, Attribute:Support Ordering Page: Merge Template Types, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("4120986C-B653-4C10-B54F-542A3168D211", "A4889D7B-87AA-419D-846C-3E618E79D875", @"True");

            // Attrib Value for Block:Merge Template Types, Attribute:Component Container Page: Merge Template Types, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("4120986C-B653-4C10-B54F-542A3168D211", "259AF14D-0214-4BE4-A7BF-40423EA07C99", @"Rock.MergeTemplates.MergeTemplateTypeContainer, Rock");



            //// Personal Merge Template Pages and Blocks

            RockMigrationHelper.AddPage("CF54E680-2E02-4F16-B54B-A2F2D29CD932", "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Merge Templates", "", "23F81A62-617A-498B-AAAC-D748F721176A", "fa fa-files-o"); // Site:Rock RMS
            RockMigrationHelper.AddPage("23F81A62-617A-498B-AAAC-D748F721176A", "D65F783D-87A9-4CC9-8110-E83466A0EADB", "Merge Template Detail", "", "F29C7AF7-6436-4C4B-BD17-330A487A4BF4", "");        // Site:Rock RMS
            RockMigrationHelper.UpdateBlockType("Merge Template List", "Displays a list of all merge templates.", "~/Blocks/Core/MergeTemplateList.ascx", "Core", "DA102F02-6DBB-42E6-BFEE-360E137B1411");
            // Add Block to Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlock("23F81A62-617A-498B-AAAC-D748F721176A", "", "DA102F02-6DBB-42E6-BFEE-360E137B1411", "Merge Template List", "Main", "", "", 0, "CCB05F67-1BB6-4443-B4ED-3E7431D2B489");

            // Add Block to Page: Merge Template Detail, Site: Rock RMS
            RockMigrationHelper.AddBlock("F29C7AF7-6436-4C4B-BD17-330A487A4BF4", "", "820DE5F9-8391-4A2A-AA87-24156882BD5F", "Merge Template Detail", "Main", "", "", 0, "73C7AF82-38D0-4C90-AD55-B8C38D751190");

            // Attrib for BlockType: Merge Template List:Detail Page
            RockMigrationHelper.AddBlockTypeAttribute("DA102F02-6DBB-42E6-BFEE-360E137B1411", "BD53F9C9-EBA9-4D3F-82EA-DE5DD34A8108", "Detail Page", "DetailPage", "", "", 0, @"", "21DA6B32-216E-4E03-AB54-5F9CD9978975");

            // Attrib for BlockType: Merge Template List:Merge Templates Ownership
            RockMigrationHelper.AddBlockTypeAttribute("DA102F02-6DBB-42E6-BFEE-360E137B1411", "7525C4CB-EE6B-41D4-9B64-A08048D5A5C0", "Merge Templates Ownership", "MergeTemplatesOwnership", "", "Set this to limit to merge templates depending on ownership type", 0, @"Personal", "85C47082-F88D-46DB-9858-52FF064ED744");

            // Attrib Value for Block:Merge Template List, Attribute:Detail Page Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("CCB05F67-1BB6-4443-B4ED-3E7431D2B489", "21DA6B32-216E-4E03-AB54-5F9CD9978975", @"f29c7af7-6436-4c4b-bd17-330a487a4bf4");

            // Attrib Value for Block:Merge Template List, Attribute:Merge Templates Ownership Page: Merge Templates, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("CCB05F67-1BB6-4443-B4ED-3E7431D2B489", "85C47082-F88D-46DB-9858-52FF064ED744", @"1");

            // Attrib Value for Block:Merge Template Detail, Attribute:Merge Templates Ownership Page: Merge Template Detail, Site: Rock RMS
            RockMigrationHelper.AddBlockAttributeValue("73C7AF82-38D0-4C90-AD55-B8C38D751190", "97860FA4-F59F-473D-A456-550FA40B937C", @"1");
        }
        /// <summary>
        /// SK: Add attributes for Smarty Streets
        /// </summary>
        private void AddAttributesForSmartyStreets()
        {
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "A75DFC58-7A1B-4799-BF31-451B2BBE38FF", "", "", "Order", "The order that this service should be used (priority)", 0, @"", "BB38037E-399B-4211-8A87-4E908E3953A1", "Order");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Active", "Should Service be used?", 0, @"False", "48F4598D-94B7-4131-9BAF-8F54308EE5FE", "Active");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "1EDAFDED-DFE6-4334-B019-6EECBA89E05A", "", "", "Use Managed API Key", "Enable this to use the Auth ID and Auth Token that is managed by Spark.", 1, @"True", "63844379-3CA1-450D-8D03-56144F6B5912", "UseManagedAPIKey");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Auth ID", "The Smarty Streets Authorization ID. NOTE: This can be left blank and will be ignored if 'Use Managed API Key' is enabled.", 2, @"", "04663026-D7A8-428E-93AD-BF524E643CC5", "AuthID");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Auth Token", "The Smarty Streets Authorization Token. NOTE: This can be left blank and will be ignored if 'Use Managed API Key' is enabled.", 3, @"", "99ECB1C8-4C1A-4DFA-B11B-9F62786A8565", "AuthToken");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Acceptable DPV Codes", "The Smarty Streets Delivery Point Validation (DPV) match code values that are considered acceptable levels of standardization (see http://smartystreets.com/kb/liveaddress-api/field-definitions#dpvmatchcode for details).", 4, @"Y,S,D", "8A7048C3-16F5-4B97-82B7-549B74C0F0D4", "AcceptableDPVCodes");
            RockMigrationHelper.UpdateEntityAttribute("Rock.Address.SmartyStreets", "9C204CD0-1233-41C5-818A-C5DA439445AA", "", "", "Acceptable Precisions", "The Smarty Streets latitude & longitude precision values that are considered acceptable levels of geocoding (see http://smartystreets.com/kb/liveaddress-api/field-definitions#precision for details).", 5, @"Zip7,Zip8,Zip9", "EA20653B-C02A-4608-9930-79EB515D33B3", "AcceptablePrecisions");

            RockMigrationHelper.UpdateAttributeQualifier("04663026-D7A8-428E-93AD-BF524E643CC5", "ispassword", @"False", "3778949A-9B29-443E-B667-482191FFDAFA");
            RockMigrationHelper.UpdateAttributeQualifier("99ECB1C8-4C1A-4DFA-B11B-9F62786A8565", "ispassword", @"False", "1E2406FA-FDBB-4D95-BBAA-E41E2B82EDBB");
            RockMigrationHelper.UpdateAttributeQualifier("8A7048C3-16F5-4B97-82B7-549B74C0F0D4", "ispassword", @"False", "5A0FA7E2-17AC-4F24-9663-FAB1D1587D2D");
            RockMigrationHelper.UpdateAttributeQualifier("EA20653B-C02A-4608-9930-79EB515D33B3", "ispassword", @"False", "ABC59D56-2422-4BAA-84F4-3D5AE5344776");
            RockMigrationHelper.AddAttributeValue("63844379-3CA1-450D-8D03-56144F6B5912", 0, @"True", "63844379-3CA1-450D-8D03-56144F6B5912");           // Use Managed API Key
            RockMigrationHelper.AddAttributeValue("8A7048C3-16F5-4B97-82B7-549B74C0F0D4", 0, @"Y,S,D", "8A7048C3-16F5-4B97-82B7-549B74C0F0D4");          // Acceptable DPV Codes
            RockMigrationHelper.AddAttributeValue("EA20653B-C02A-4608-9930-79EB515D33B3", 0, @"Zip7,Zip8,Zip9", "EA20653B-C02A-4608-9930-79EB515D33B3"); // Acceptable Precisions
            Sql(@"-- First see if any location services are enabled
                DECLARE @EnabledLocationServicesCount INT =
                 (SELECT COUNT(*)
                 FROM [EntityType] t
                 JOIN [Attribute] a on t.[Id] = a.[EntityTypeId]
                 JOIN [AttributeValue] v on a.[Id] = v.[AttributeId]
                 WHERE t.[Name] LIKE 'Rock.Address.%'
                  AND a.[Key] = 'Active'
                  AND v.[Value] = 'True')
                -- If nothing is enabled then find the SmartyStreets AttributeValue and set it to True
                IF (@EnabledLocationServicesCount = 0)
                BEGIN
                 DECLARE @SmartyStreetsAttributeValueId INT =
                  (SELECT v.[Id]
                  FROM [Attribute] a 
                  JOIN [AttributeValue] v ON a.[Id] = v.[AttributeId]
                  WHERE a.[Guid] = '48F4598D-94B7-4131-9BAF-8F54308EE5FE')
                 -- If an attibute value already exists then update
                 IF (@SmartyStreetsAttributeValueId > 0)
                 BEGIN
                  UPDATE [AttributeValue]
                  SET [Value] = 'True'
                  WHERE [Id] = @SmartyStreetsAttributeValueId
                 END
                 ELSE
                 BEGIN
                 -- Otherwise insert
                  DECLARE @SmartyStreetsAttributeId INT =
                   (SELECT [Id]
                   FROM [Attribute]
                   WHERE [Guid] = '48F4598D-94B7-4131-9BAF-8F54308EE5FE')
                  IF (@SmartyStreetsAttributeId > 0)
                  BEGIN
                   INSERT INTO [AttributeValue]([IsSystem], [AttributeId], [EntityId], [Value], [Guid])
                   VALUES (
                    0 --[IsSystem]
                    , @SmartyStreetsAttributeId --[AttributeId]
                    , 0 --[EntityId]
                    , 'True' --[Value]
                    , '48F4598D-94B7-4131-9BAF-8F54308EE5FE') --[Guid]
                  END
                 END
                END");
        }