public void Execute(IJobExecutionContext context)
        {
            // Get job settings
            var dataMap         = context.JobDetail.JobDataMap;
            var systemEmailGuid = dataMap.GetString("Email").AsGuidOrNull();
            var groupGuid       = dataMap.GetString("Group").AsGuidOrNull();
            var previousMinutes = dataMap.GetString("PreviousMinutes").AsIntegerOrNull();

            // Ensure job settings aren't null
            if (systemEmailGuid == null || previousMinutes == null || groupGuid == null)
            {
                throw new Exception("Missing one or more job settings.");
            }

            var rockContext = new RockContext();

            var systemEmail = new SystemEmailService(rockContext).Get(systemEmailGuid.Value);
            var group       = new GroupService(rockContext).Get(groupGuid.Value);

            if (systemEmail == null || group == null)
            {
                throw new Exception("One or more job settings incorrect.");
            }

            string appRoot      = Rock.Web.Cache.GlobalAttributesCache.Read().GetValue("ExternalApplicationRoot");
            var    cutOffBegins = RockDateTime.Now.AddMinutes(-previousMinutes.Value);

            var scheduledTransactions = new FinancialScheduledTransactionService(rockContext)
                                        .Queryable("FinancialPaymentDetail")
                                        .Where(s => s.IsActive && s.CreatedDateTime >= cutOffBegins)
                                        .ToList();

            if (scheduledTransactions.Count > 1)
            {
                foreach (var groupMember in group.Members)
                {
                    var mergeFields = new Dictionary <string, object> {
                        { "Transactions", scheduledTransactions }
                    };

                    var recipients = new List <string>()
                    {
                        groupMember.Person.Email
                    };

                    Email.Send(systemEmail.From.ResolveMergeFields(mergeFields), systemEmail.FromName.ResolveMergeFields(mergeFields), systemEmail.Subject.ResolveMergeFields(mergeFields), recipients, systemEmail.Body.ResolveMergeFields(mergeFields), appRoot, null);
                }
                context.Result = string.Format("{0} transactions were sent ", scheduledTransactions.Count());
            }
            else
            {
                context.Result = "No new transactions to send.";
            }
        }
Example #2
0
        /// <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);
            }

            if (systemEmail == null)
            {
                throw new Exception("Expiring credit card email is missing.");
            }

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

            if (workflowGuid != null)
            {
                workflowType = WorkflowTypeCache.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();

            // Get the current month and year
            DateTime now     = DateTime.Now;
            int      month   = now.Month;
            int      year    = now.Year;
            int      counter = 0;
            var      errors  = new List <string>();

            foreach (var transaction in qry)
            {
                int?expirationMonthDecrypted = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationMonthEncrypted).AsIntegerOrNull();
                int?expirationYearDecrypted  = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationYearEncrypted).AsIntegerOrNull();
                if (expirationMonthDecrypted.HasValue && expirationMonthDecrypted.HasValue)
                {
                    string acctNum = string.Empty;

                    if (!string.IsNullOrEmpty(transaction.FinancialPaymentDetail.AccountNumberMasked) && transaction.FinancialPaymentDetail.AccountNumberMasked.Length >= 4)
                    {
                        acctNum = transaction.FinancialPaymentDetail.AccountNumberMasked.Substring(transaction.FinancialPaymentDetail.AccountNumberMasked.Length - 4);
                    }

                    int warningYear  = expirationYearDecrypted.Value;
                    int warningMonth = expirationMonthDecrypted.Value - 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;

                        if (!person.IsEmailActive || person.Email.IsNullOrWhiteSpace() || person.EmailPreference == EmailPreference.DoNotEmail)
                        {
                            continue;
                        }

                        mergeFields.Add("Person", person);
                        mergeFields.Add("Card", acctNum);
                        mergeFields.Add("Expiring", expirationDate);
                        recipients.Add(new RecipientData(person.Email, mergeFields));

                        var emailMessage = new RockEmailMessage(systemEmail.Guid);
                        emailMessage.SetRecipients(recipients);

                        var emailErrors = new List <string>();
                        emailMessage.Send(out emailErrors);
                        errors.AddRange(emailErrors);

                        // 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);

            if (errors.Any())
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine();
                sb.Append(string.Format("{0} Errors: ", errors.Count()));
                errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                string errorMessage = sb.ToString();
                context.Result += errorMessage;
                var         exception = new Exception(errorMessage);
                HttpContext context2  = HttpContext.Current;
                ExceptionLogService.LogException(exception, context2);
                throw exception;
            }
        }