/// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Execute( IJobExecutionContext context )
        {
            var rockContext = new RockContext();
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // Get the details for the email that we'll be sending out.
            Guid? systemEmailGuid = dataMap.GetString( "ExpiringCreditCardEmail" ).AsGuidOrNull();
            SystemEmailService emailService = new SystemEmailService( rockContext );
            SystemEmail systemEmail = null;

            if ( systemEmailGuid.HasValue )
            {
                systemEmail = emailService.Get( systemEmailGuid.Value );
            }

            // Fetch the configured Workflow once if one was set, we'll use it later.
            Guid? workflowGuid = dataMap.GetString( "Workflow" ).AsGuidOrNull();
            WorkflowType workflowType = null;
            var workflowTypeService = new WorkflowTypeService( rockContext );
            var workflowService = new WorkflowService( rockContext );

            if ( workflowGuid != null )
            {
                workflowType = workflowTypeService.Get( workflowGuid.Value );
            }

            var qry = new FinancialScheduledTransactionService( rockContext )
                .Queryable( "ScheduledTransactionDetails,FinancialPaymentDetail.CurrencyTypeValue,FinancialPaymentDetail.CreditCardTypeValue" )
                .Where( t => t.IsActive && t.FinancialPaymentDetail.ExpirationMonthEncrypted != null
                && ( t.EndDate == null || t.EndDate > DateTime.Now ) )
                .AsNoTracking();

            var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "PublicApplicationRoot" );

            // Get the current month and year
            DateTime now = DateTime.Now;
            int month = now.Month;
            int year = now.Year;
            int counter = 0;
            foreach ( var transaction in qry )
            {
                int expirationMonthDecrypted = Int32.Parse( Encryption.DecryptString( transaction.FinancialPaymentDetail.ExpirationMonthEncrypted ) );
                int expirationYearDecrypted = Int32.Parse( Encryption.DecryptString( transaction.FinancialPaymentDetail.ExpirationYearEncrypted ) );
                string acctNum = transaction.FinancialPaymentDetail.AccountNumberMasked.Substring( transaction.FinancialPaymentDetail.AccountNumberMasked.Length - 4 );

                int warningYear = expirationYearDecrypted;
                int warningMonth = expirationMonthDecrypted - 1;
                if ( warningMonth == 0 )
                {
                    warningYear -= 1;
                    warningMonth = 12;
                }

                string warningDate = warningMonth.ToString() + warningYear.ToString();
                string currentMonthString = month.ToString() + year.ToString();

                if ( warningDate == currentMonthString )
                {
                    // as per ISO7813 https://en.wikipedia.org/wiki/ISO/IEC_7813
                    var expirationDate = string.Format( "{0:D2}/{1:D2}", expirationMonthDecrypted, expirationYearDecrypted );

                    var recipients = new List<RecipientData>();
                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null );
                    var person = transaction.AuthorizedPersonAlias.Person;
                    mergeFields.Add( "Person", person );
                    mergeFields.Add( "Card", acctNum );
                    mergeFields.Add( "Expiring", expirationDate );
                    recipients.Add( new RecipientData( person.Email, mergeFields ) );

                    Email.Send( systemEmail.Guid, recipients, appRoot );

                    // Start workflow for this person
                    if ( workflowType != null )
                    {
                        Dictionary<string, string> attributes = new Dictionary<string, string>();
                        attributes.Add( "Person", transaction.AuthorizedPersonAlias.Guid.ToString() );
                        attributes.Add( "Card", acctNum );
                        attributes.Add( "Expiring", expirationDate );
                        StartWorkflow( workflowService, workflowType, attributes, string.Format( "{0} (scheduled transaction Id: {1})", person.FullName, transaction.Id ) );
                    }

                    counter++;
                }
            }

            context.Result = string.Format( "{0} scheduled credit card transactions were examined with {1} notice(s) sent.", qry.Count(), counter );
        }