/// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var gateway = new FinancialGatewayService(rockContext).Get(GatewayId);
                if (gateway != null)
                {
                    var gatewayComponent = gateway.GetGatewayComponent();
                    if (gatewayComponent != null)
                    {
                        var scheduledTxnService = new FinancialScheduledTransactionService(rockContext);

                        foreach (var txnId in ScheduledTransactionIds)
                        {
                            var scheduledTxn = scheduledTxnService.Get(txnId);
                            if (scheduledTxn != null)
                            {
                                string statusMsgs = string.Empty;
                                gatewayComponent.GetScheduledPaymentStatus(scheduledTxn, out statusMsgs);
                                rockContext.SaveChanges();
                            }
                        }
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Gets the supported gateway ids.
        /// </summary>
        /// <returns></returns>
        private List <int> GetSupportedGatewayIds()
        {
            if (_supportedGatewayIds == null)
            {
                var rockContext              = GetRockContext();
                var gatewayService           = new FinancialGatewayService(rockContext);
                var activeGatewayEntityTypes = gatewayService.Queryable("EntityType").AsNoTracking()
                                               .Where(fg => fg.IsActive)
                                               .GroupBy(fg => fg.EntityType)
                                               .ToList();

                var supportedTypes = Rock.Reflection.FindTypes(typeof(IAutomatedGatewayComponent));
                _supportedGatewayIds = new List <int>();

                foreach (var entityType in activeGatewayEntityTypes)
                {
                    if (supportedTypes.Any(t => t.Value.FullName == entityType.Key.Name))
                    {
                        _supportedGatewayIds.AddRange(entityType.Select(fg => fg.Id));
                    }
                }
            }

            return(_supportedGatewayIds);
        }
        /// <summary>
        /// Gets the edit value as the IEntity.Id
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <returns></returns>
        public int?GetEditValueAsEntityId(Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            var guid = GetEditValue(control, configurationValues).AsGuid();
            var item = new FinancialGatewayService(new RockContext()).Get(guid);

            return(item != null ? item.Id : ( int? )null);
        }
        /// <summary>
        /// Sets the edit value from IEntity.Id value
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="id">The identifier.</param>
        public void SetEditValueFromEntityId(Control control, Dictionary <string, ConfigurationValue> configurationValues, int?id)
        {
            var item      = new FinancialGatewayService(new RockContext()).Get(id ?? 0);
            var guidValue = item != null?item.Guid.ToString() : string.Empty;

            SetEditValue(control, configurationValues, guidValue);
        }
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using ( var rockContext = new RockContext() )
            {
                var gateway = new FinancialGatewayService( rockContext ).Get( GatewayId );
                if ( gateway != null )
                {
                    var gatewayComponent = gateway.GetGatewayComponent();
                    if ( gatewayComponent != null )
                    {
                        var scheduledTxnService = new FinancialScheduledTransactionService( rockContext );

                        foreach( var txnId in ScheduledTransactionIds )
                        {
                            var scheduledTxn = scheduledTxnService.Get( txnId );
                            if ( scheduledTxn != null )
                            {
                                string statusMsgs = string.Empty;
                                gatewayComponent.GetScheduledPaymentStatus( scheduledTxn, out statusMsgs );
                                rockContext.SaveChanges();
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Shows the inactive gatway message.
        /// </summary>
        /// <param name="financialGateway">The financial gateway.</param>
        private void ShowInactiveGatwayMessage(FinancialGateway financialGateway)
        {
            nbIsActiveWarning.Text = "An 'Inactive' status will prevent the gateway from being shown in the gateway picker for Registration templates if it is not already selected. An 'Inactive' status DOES NOT prevent charges from being processed for a registration where the gateway is already assigned.";

            if (cbIsActive.Checked)
            {
                nbIsActiveWarning.Visible = false;
                return;
            }

            nbIsActiveWarning.Visible = true;

            if (financialGateway == null || financialGateway.Id == 0)
            {
                // This is a new gateway so show the message but don't bother looking for registrations using it.
                return;
            }

            var activeRegistrations = new FinancialGatewayService(new RockContext()).GetRegistrationTemplatesForGateway(financialGateway.Id, false).ToList();

            if (!activeRegistrations.Any())
            {
                // This gateway isn't used by any registrations so show the message but don't bother looking for registrations using it.
                return;
            }

            var registrationNames = " To prevent this choose a different payment gateway for these registrations: <b>'" + string.Join("', '", activeRegistrations.Select(r => r.Name)).Trim().TrimEnd(',') + "'</b>";

            nbIsActiveWarning.Text += registrationNames;
        }
Exemple #7
0
        public HttpResponseMessage StopScheduledGiving(int id)
        {
            var rockContext = new RockContext();

            try
            {
                rockContext.WrapTransaction(() =>
                {
                    var gatewayComponent = GatewayContainer.GetComponent(gatewayName);

                    if (gatewayComponent == null)
                    {
                        GenerateResponse(HttpStatusCode.InternalServerError, "There was a problem creating the gateway component");
                    }

                    var financialGateway = new FinancialGatewayService(rockContext).Queryable().FirstOrDefault(g => g.EntityTypeId == gatewayComponent.EntityType.Id);

                    if (financialGateway == null)
                    {
                        GenerateResponse(HttpStatusCode.InternalServerError, "There was a problem creating the financial gateway");
                    }

                    var schedule = (new FinancialScheduledTransactionService(rockContext)).Get(id);

                    if (schedule == null)
                    {
                        GenerateResponse(HttpStatusCode.BadRequest, "No schedule with Id: " + id);
                    }

                    string errorMessage;
                    var error = gatewayComponent.CancelScheduledPayment(schedule, out errorMessage);

                    if (error || errorMessage != null)
                    {
                        GenerateResponse(HttpStatusCode.InternalServerError, errorMessage ?? "There was an error with the gateway");
                    }

                    schedule.IsActive = false;
                    rockContext.SaveChanges();
                });
            }
            catch (HttpResponseException exception)
            {
                return(exception.Response);
            }
            catch (Exception exception)
            {
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
                response.Content = new StringContent(exception.Message);
                return(response);
            }

            return(new HttpResponseMessage(HttpStatusCode.OK));
        }
Exemple #8
0
        private FinancialGateway GetGateway(RockContext rockContext, string attributeName)
        {
            var  financialGatewayService = new FinancialGatewayService(rockContext);
            Guid?ccGatewayGuid           = GetAttributeValue(attributeName).AsGuidOrNull();

            if (ccGatewayGuid.HasValue)
            {
                return(financialGatewayService.Get(ccGatewayGuid.Value));
            }
            return(null);
        }
        public void RockCleanup_Execute_ShouldUpdatePeopleWithFinancialPersonSavedAccountToAccountProtectionProfileHigh()
        {
            var personGuid = Guid.NewGuid();
            var personWithFinancialPersonBankAccount = new Person
            {
                FirstName = "Test",
                LastName  = personGuid.ToString(),
                Email     = $"{personGuid}@test.com",
                Guid      = personGuid
            };

            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);
                personService.Add(personWithFinancialPersonBankAccount);
                rockContext.SaveChanges();

                personWithFinancialPersonBankAccount = personService.Get(personWithFinancialPersonBankAccount.Id);

                var financialGateway    = new FinancialGatewayService(rockContext).Get("6432D2D2-32FF-443D-B5B3-FB6C8414C3AD".AsGuid());
                var creditCardTypeValue = DefinedTypeCache.Get(SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE.AsGuid()).DefinedValues.OrderBy(a => Guid.NewGuid()).First().Id;
                var currencyTypeValue   = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid()).Id;
                var definedValueService = new DefinedValueService(rockContext);

                var financialPersonSavedAccount = new FinancialPersonSavedAccount
                {
                    Name                   = "Test Saved Account",
                    PersonAliasId          = personWithFinancialPersonBankAccount.PrimaryAliasId.Value,
                    FinancialGateway       = financialGateway,
                    FinancialPaymentDetail = new FinancialPaymentDetail
                    {
                        AccountNumberMasked = "1111",
                        CreditCardTypeValue = definedValueService.Get(creditCardTypeValue),
                        CurrencyTypeValue   = definedValueService.Get(currencyTypeValue),
                        NameOnCard          = "Test User"
                    }
                };

                var service = new FinancialPersonSavedAccountService(rockContext);
                service.Add(financialPersonSavedAccount);
                rockContext.SaveChanges();
            }

            ExecuteRockCleanupJob();

            using (var rockContext = new RockContext())
            {
                var actualPerson = new PersonService(rockContext).Get(personGuid);
                Assert.That.AreEqual(AccountProtectionProfile.High, actualPerson.AccountProtectionProfile);
            }
        }
        /// <summary>
        /// Returns the field's current value(s)
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">Information about the value</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param>
        /// <returns></returns>
        public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed)
        {
            string formattedValue = string.Empty;

            Guid?financialGatewayGuid = value.AsGuidOrNull();

            if (financialGatewayGuid.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var financialGatewayName = new FinancialGatewayService(rockContext).GetSelect(financialGatewayGuid.Value, s => s.Name);
                    formattedValue = financialGatewayName;
                }
            }

            return(base.FormatValue(parentControl, formattedValue, null, condensed));
        }
        /// <summary>
        /// Returns the field's current value(s)
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">Information about the value</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param>
        /// <returns></returns>
        public override string FormatValue( Control parentControl, string value, Dictionary<string, ConfigurationValue> configurationValues, bool condensed )
        {
            string formattedValue = string.Empty;

            Guid? financialGatewayGuid = value.AsGuidOrNull();
            if ( financialGatewayGuid.HasValue )
            {
                using ( var rockContext = new RockContext() )
                {
                    var financialGateway = new FinancialGatewayService( rockContext ).Get( financialGatewayGuid.Value );
                    if ( financialGateway != null )
                    {
                        formattedValue = financialGateway.Name;
                    }
                }
            }

            return base.FormatValue( parentControl, formattedValue, null, condensed );
        }
Exemple #12
0
        private FinancialGateway GetSelectedGateway()
        {
            int?gatewayId = gpGateway.SelectedValueAsInt();

            if (gatewayId.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var financialGateway = new FinancialGatewayService(rockContext).Get(gatewayId.Value);
                    if (financialGateway != null)
                    {
                        financialGateway.LoadAttributes(rockContext);
                        return(financialGateway);
                    }
                }
            }

            return(null);
        }
Exemple #13
0
 /// <summary>
 /// Reads new values entered by the user for the field
 /// </summary>
 /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
 /// <param name="configurationValues"></param>
 /// <returns></returns>
 public override string GetEditValue(Control control, Dictionary <string, ConfigurationValue> configurationValues)
 {
     if (control != null && control is FinancialGatewayPicker)
     {
         int id = int.MinValue;
         if (Int32.TryParse(((FinancialGatewayPicker)control).SelectedValue, out id))
         {
             using (var rockContext = new RockContext())
             {
                 var financialGateway = new FinancialGatewayService(rockContext).Get(id);
                 if (financialGateway != null)
                 {
                     return(financialGateway.Guid.ToString());
                 }
             }
         }
     }
     return(null);
 }
Exemple #14
0
        /// <summary>
        /// Create a new payment processor to handle a single automated payment.
        /// </summary>
        /// <param name="currentPersonAliasId">The current user's person alias ID. Possibly the REST user.</param>
        /// <param name="automatedPaymentArgs">The arguments describing how to charge the payment and store the resulting transaction</param>
        /// <param name="rockContext">The context to use for loading and saving entities</param>
        /// <param name="enableDuplicateChecking">If false, the payment will be charged even if there is a similar transaction for the same person
        /// within a short time period.</param>
        /// <param name="enableScheduleAdherenceProtection">If false and a schedule is indicated in the args, the payment will be charged even if
        /// the schedule has already been processed according to it's frequency.</param>
        public AutomatedPaymentProcessor(int?currentPersonAliasId, AutomatedPaymentArgs automatedPaymentArgs, RockContext rockContext, bool enableDuplicateChecking = true, bool enableScheduleAdherenceProtection = true)
        {
            _rockContext                       = rockContext;
            _automatedPaymentArgs              = automatedPaymentArgs;
            _currentPersonAliasId              = currentPersonAliasId;
            _enableDuplicateChecking           = enableDuplicateChecking;
            _enableScheduleAdherenceProtection = enableScheduleAdherenceProtection;
            _futureTransaction                 = null;

            _personAliasService                   = new PersonAliasService(_rockContext);
            _financialGatewayService              = new FinancialGatewayService(_rockContext);
            _financialAccountService              = new FinancialAccountService(_rockContext);
            _financialPersonSavedAccountService   = new FinancialPersonSavedAccountService(_rockContext);
            _financialBatchService                = new FinancialBatchService(_rockContext);
            _financialTransactionService          = new FinancialTransactionService(_rockContext);
            _financialScheduledTransactionService = new FinancialScheduledTransactionService(_rockContext);

            _payment = null;
        }
Exemple #15
0
        /// <summary>
        /// Sets the value where the value is a FinancialGateway.Guid (or null)
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues"></param>
        /// <param name="value">The value.</param>
        public override void SetEditValue(Control control, Dictionary <string, ConfigurationValue> configurationValues, string value)
        {
            var picker = control as FinancialGatewayPicker;

            if (picker != null)
            {
                int? itemId   = null;
                Guid?itemGuid = value.AsGuidOrNull();
                if (itemGuid.HasValue)
                {
                    using (var rockContext = new RockContext())
                    {
                        itemId = new FinancialGatewayService(rockContext).Queryable().Where(a => a.Guid == itemGuid.Value).Select(a => ( int? )a.Id).FirstOrDefault();
                    }
                }

                picker.SetValue(itemId);
            }
        }
Exemple #16
0
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues"></param>
        /// <param name="value">The value.</param>
        public override void SetEditValue(Control control, Dictionary <string, ConfigurationValue> configurationValues, string value)
        {
            Guid financialGatewayGuid = Guid.Empty;

            if (Guid.TryParse(value, out financialGatewayGuid))
            {
                if (control != null && control is FinancialGatewayPicker)
                {
                    using (var rockContext = new RockContext())
                    {
                        var financialGateway = new FinancialGatewayService(rockContext).Get(financialGatewayGuid);
                        if (financialGateway != null)
                        {
                            ((FinancialGatewayPicker)control).SetValue(financialGateway.Id.ToString());
                        }
                    }
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="gatewayId">The gateway identifier.</param>
        public void ShowDetail(int gatewayId)
        {
            FinancialGateway gateway = null;

            bool editAllowed = IsUserAuthorized(Authorization.EDIT);

            if (!gatewayId.Equals(0))
            {
                gateway     = new FinancialGatewayService(new RockContext()).Get(gatewayId);
                editAllowed = editAllowed || gateway.IsAuthorized(Authorization.EDIT, CurrentPerson);
                pdAuditDetails.SetEntity(gateway, ResolveRockUrl("~"));
            }

            if (gateway == null)
            {
                gateway = new FinancialGateway {
                    Id = 0, IsActive = true
                };
                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            GatewayId = gateway.Id;

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!editAllowed || !IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(FinancialGateway.FriendlyTypeName);
            }

            if (readOnly)
            {
                ShowReadonlyDetails(gateway);
            }
            else
            {
                ShowEditDetails(gateway);
            }
        }
        /// <summary>
        /// Shows the details.
        /// </summary>
        protected void ShowDetails()
        {
            var migrateSavedAccountsResultSummary = this.GetBlockUserPreference("MigrateSavedAccountsResultSummary");
            var migrateSavedAccountsResultDetails = this.GetBlockUserPreference("MigrateSavedAccountsResultDetails");

            if (migrateSavedAccountsResultSummary.IsNotNullOrWhiteSpace())
            {
                nbMigrateSavedAccounts.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                nbMigrateSavedAccounts.Text    = "Migrate Saved Accounts has already been run.";
                nbMigrateSavedAccounts.Details = migrateSavedAccountsResultDetails.ToString().ConvertCrLfToHtmlBr();
            }

            var migrateScheduledTransactionsResultSummary = this.GetBlockUserPreference("MigrateScheduledTransactionsResultSummary");
            var migrateScheduledTransactionsResultDetails = this.GetBlockUserPreference("MigrateScheduledTransactionsResultDetails");

            if (migrateScheduledTransactionsResultSummary.IsNotNullOrWhiteSpace())
            {
                nbMigrateScheduledTransactions.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                nbMigrateScheduledTransactions.Text    = "Migrate Scheduled Transactions has already been run.";
                nbMigrateScheduledTransactions.Details = migrateScheduledTransactionsResultDetails.ToString().ConvertCrLfToHtmlBr();
            }

            var rockContext             = new RockContext();
            var financialGatewayService = new FinancialGatewayService(rockContext);
            var activeGatewayList       = financialGatewayService.Queryable().Where(a => a.IsActive == true).AsNoTracking().ToList();
            var piGateways = activeGatewayList.Where(a => a.GetGatewayComponent() is Rock.TransNational.Pi.PiGateway).ToList();

            ddlPiGateway.Items.Clear();
            foreach (var piGateway in piGateways)
            {
                ddlPiGateway.Items.Add(new ListItem(piGateway.Name, piGateway.Id.ToString()));
            }

            var nmiGateways = activeGatewayList.Where(a => a.GetGatewayComponent() is Rock.NMI.Gateway).ToList();

            ddlNMIGateway.Items.Clear();
            foreach (var nmiGateway in nmiGateways)
            {
                ddlNMIGateway.Items.Add(new ListItem(nmiGateway.Name, nmiGateway.Id.ToString()));
            }
        }
Exemple #19
0
        /// <summary>
        /// Gets the value of the selected FinancialGateway as the FinancialGateway.Guid as a string
        /// </summary>
        /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
        /// <param name="configurationValues"></param>
        /// <returns></returns>
        public override string GetEditValue(Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            var picker = control as FinancialGatewayPicker;

            if (picker != null)
            {
                int? itemId   = picker.SelectedValue.AsIntegerOrNull();
                Guid?itemGuid = null;
                if (itemId.HasValue)
                {
                    using (var rockContext = new RockContext())
                    {
                        itemGuid = new FinancialGatewayService(rockContext).Queryable().Where(a => a.Id == itemId.Value).Select(a => ( Guid? )a.Guid).FirstOrDefault();
                    }
                }

                return(itemGuid?.ToString());
            }

            return(null);
        }
        /// <summary>
        /// Binds the Gateway list grid.
        /// </summary>
        private void BindGrid()
        {
            using (var rockContext = new RockContext())
            {
                var qry = new FinancialGatewayService(rockContext)
                          .Queryable("EntityType").AsNoTracking();

                SortProperty sortProperty = rGridGateway.SortProperty;
                if (sortProperty != null)
                {
                    qry = qry.Sort(sortProperty);
                }
                else
                {
                    qry = qry.OrderBy(g => g.Name);
                }

                rGridGateway.DataSource = qry.ToList();
                rGridGateway.DataBind();
            }
        }
        /// <summary>
        /// Handles the Delete event of the rGridGateway control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void rGridGateway_Delete(object sender, RowEventArgs e)
        {
            var rockContext    = new RockContext();
            var gatewayService = new FinancialGatewayService(rockContext);
            var gateway        = gatewayService.Get(e.RowKeyId);

            if (gateway != null)
            {
                string errorMessage;
                if (!gatewayService.CanDelete(gateway, out errorMessage))
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                    return;
                }

                gatewayService.Delete(gateway);
                rockContext.SaveChanges();
            }

            BindGrid();
        }
Exemple #22
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="gatewayId">The gateway identifier.</param>
        public void ShowDetail( int gatewayId )
        {
            FinancialGateway gateway = null;

            bool editAllowed = IsUserAuthorized( Authorization.EDIT );

            if ( !gatewayId.Equals( 0 ) )
            {
                gateway = new FinancialGatewayService( new RockContext() ).Get( gatewayId );
                editAllowed = editAllowed || gateway.IsAuthorized( Authorization.EDIT, CurrentPerson );
                pdAuditDetails.SetEntity( gateway, ResolveRockUrl( "~" ) );
            }

            if ( gateway == null )
            {
                gateway = new FinancialGateway { Id = 0, IsActive = true };
                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            GatewayId = gateway.Id;

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if ( !editAllowed || !IsUserAuthorized( Authorization.EDIT ) )
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( FinancialGateway.FriendlyTypeName );
            }

            if ( readOnly )
            {
                ShowReadonlyDetails( gateway );
            }
            else
            {
                ShowEditDetails( gateway );
            }
        }
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="gatewayId">The gateway identifier.</param>
        public void ShowDetail(int gatewayId)
        {
            FinancialGateway gateway = null;

            bool editAllowed = IsUserAuthorized(Authorization.EDIT);

            if (!gatewayId.Equals(0))
            {
                gateway     = new FinancialGatewayService(new RockContext()).Get(gatewayId);
                editAllowed = editAllowed || gateway.IsAuthorized(Authorization.EDIT, CurrentPerson);
            }

            if (gateway == null)
            {
                gateway = new FinancialGateway {
                    Id = 0, IsActive = true
                };
            }

            GatewayId = gateway.Id;

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!editAllowed || !IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(FinancialGateway.FriendlyTypeName);
            }

            if (readOnly)
            {
                ShowReadonlyDetails(gateway);
            }
            else
            {
                ShowEditDetails(gateway);
            }
        }
Exemple #24
0
        private FinancialGateway GetFinancialGateway(FinancialGateway financialGateway, int?financialGatewayId)
        {
            if (financialGateway != null)
            {
                if (financialGateway.Attributes == null)
                {
                    financialGateway.LoadAttributes();
                }
                return(financialGateway);
            }

            if (financialGatewayId.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var gateway = new FinancialGatewayService(rockContext).Get(financialGatewayId.Value);
                    gateway.LoadAttributes(rockContext);
                    return(gateway);
                }
            }

            return(null);
        }
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="gatewayId">The gateway identifier.</param>
        public void ShowDetail( int gatewayId )
        {
            FinancialGateway gateway = null;

            bool editAllowed = IsUserAuthorized( Authorization.EDIT );

            if ( !gatewayId.Equals( 0 ) )
            {
                gateway = new FinancialGatewayService( new RockContext() ).Get( gatewayId );
                editAllowed = editAllowed || gateway.IsAuthorized( Authorization.EDIT, CurrentPerson );
            }

            if ( gateway == null )
            {
                gateway = new FinancialGateway { Id = 0, IsActive = true };
            }

            GatewayId = gateway.Id;

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if ( !editAllowed || !IsUserAuthorized( Authorization.EDIT ) )
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( FinancialGateway.FriendlyTypeName );
            }

            if ( readOnly )
            {
                ShowReadonlyDetails( gateway );
            }
            else
            {
                ShowEditDetails( gateway );
            }
        }
Exemple #26
0
        /// <summary>
        /// Create a new payment processor to handle a single automated payment from a future transaction (probably generated from text-to-give).
        /// </summary>
        /// <param name="futureTransaction">The transaction with a FutureProcessingDateTime</param>
        /// <param name="rockContext">The context to use for loading and saving entities</param>
        public AutomatedPaymentProcessor(FinancialTransaction futureTransaction, RockContext rockContext)
        {
            _rockContext          = rockContext;
            _automatedPaymentArgs = null;
            _currentPersonAliasId = futureTransaction.CreatedByPersonAliasId;
            _futureTransaction    = futureTransaction;

            // The job charging these future transactions could have a variable run frequency and be charging a days worth at a time, so the duplicate
            // checking could very easily provide false positives. Therefore, we rely on the "dry-run" to have previously validated
            _enableDuplicateChecking           = false; // These future transactions should have already had a "dry-run" and been validated.
            _enableScheduleAdherenceProtection = false; // These future transactions should have already had a "dry-run" and been validated

            _personAliasService                   = new PersonAliasService(_rockContext);
            _financialGatewayService              = new FinancialGatewayService(_rockContext);
            _financialAccountService              = new FinancialAccountService(_rockContext);
            _financialPersonSavedAccountService   = new FinancialPersonSavedAccountService(_rockContext);
            _financialBatchService                = new FinancialBatchService(rockContext);
            _financialTransactionService          = new FinancialTransactionService(_rockContext);
            _financialScheduledTransactionService = new FinancialScheduledTransactionService(_rockContext);

            _payment = null;

            CopyFutureTransactionToArgs();
        }
        /// <summary>
        /// Binds the Gateway list grid.
        /// </summary>
        private void BindGrid()
        {
            using (var rockContext = new RockContext())
            {
                var qry = new FinancialGatewayService(rockContext)
                          .Queryable("EntityType").AsNoTracking();

                SortProperty sortProperty = rGridGateway.SortProperty;
                if (sortProperty != null)
                {
                    qry = qry.Sort(sortProperty);
                }
                else
                {
                    qry = qry.OrderBy(g => g.Name);
                }

                var gateways = qry.ToList();
                nbInactiveWarning.Visible = gateways.Where(g => g.IsActive == false).Any();

                rGridGateway.DataSource = gateways;
                rGridGateway.DataBind();
            }
        }
Exemple #28
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            if (!ScheduledTransactionIds.Any())
            {
                return;
            }

            using (var rockContext = new RockContext())
            {
                var gateway = new FinancialGatewayService(rockContext).Get(GatewayId);
                if (gateway != null)
                {
                    var gatewayComponent = gateway.GetGatewayComponent();
                    if (gatewayComponent != null)
                    {
                        var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext);
                        var financialTransactionService          = new FinancialTransactionService(rockContext);

                        foreach (var scheduledTransactionId in ScheduledTransactionIds)
                        {
                            var financialScheduledTransaction = financialScheduledTransactionService.Get(scheduledTransactionId);
                            if (financialScheduledTransaction != null)
                            {
                                string statusMsgs = string.Empty;
                                gatewayComponent.GetScheduledPaymentStatus(financialScheduledTransaction, out statusMsgs);

                                var lastTransactionDateTime = financialTransactionService.Queryable().Where(a => a.ScheduledTransactionId == scheduledTransactionId).Max(a => ( DateTime? )a.TransactionDateTime);
                                financialScheduledTransaction.NextPaymentDate = gatewayComponent.GetNextPaymentDate(financialScheduledTransaction, lastTransactionDateTime);

                                rockContext.SaveChanges();
                            }
                        }
                    }
                }
            }
        }
        //
        // Swipe Panel Events
        //
        private void ProcessSwipe( string swipeData )
        {
            try
            {
                using ( var rockContext = new RockContext() )
                {
                    // create swipe object
                    SwipePaymentInfo swipeInfo = new SwipePaymentInfo( swipeData );
                    swipeInfo.Amount = this.Amounts.Sum( a => a.Value );

                    // if not anonymous then add contact info to the gateway transaction
                    if ( this.AnonymousGiverPersonAliasId != this.SelectedGivingUnit.PersonAliasId )
                    {
                        var giver = new PersonAliasService( rockContext ).Queryable( "Person, Person.PhoneNumbers" ).Where( p => p.Id == this.SelectedGivingUnit.PersonAliasId ).FirstOrDefault();
                        swipeInfo.FirstName = giver.Person.NickName;
                        swipeInfo.LastName = giver.Person.LastName;

                        if ( giver.Person.PhoneNumbers != null )
                        {
                            Guid homePhoneValueGuid = new Guid( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME );
                            var homephone = giver.Person.PhoneNumbers.Where( p => p.NumberTypeValue.Guid == homePhoneValueGuid ).FirstOrDefault();
                            if ( homephone != null )
                            {
                                swipeInfo.Phone = homephone.NumberFormatted;
                            }
                        }

                        var homeLocation = giver.Person.GetHomeLocation();

                        if ( homeLocation != null )
                        {
                            swipeInfo.Street1 = homeLocation.Street1;

                            if ( !string.IsNullOrWhiteSpace( homeLocation.Street2 ) )
                            {
                                swipeInfo.Street2 = homeLocation.Street2;
                            }

                            swipeInfo.City = homeLocation.City;
                            swipeInfo.State = homeLocation.State;
                            swipeInfo.PostalCode = homeLocation.PostalCode;
                        }

                    }

                    // add comment to the transation
                    swipeInfo.Comment1 = GetAttributeValue( "PaymentComment" );

                    // get gateway
                    FinancialGateway financialGateway = null;
                    GatewayComponent gateway = null;
                    Guid? gatewayGuid = GetAttributeValue( "CreditCardGateway" ).AsGuidOrNull();
                    if ( gatewayGuid.HasValue )
                    {
                        financialGateway = new FinancialGatewayService( rockContext ).Get( gatewayGuid.Value );
                        if ( financialGateway != null )
                        {
                            financialGateway.LoadAttributes( rockContext );
                        }
                        gateway = financialGateway.GetGatewayComponent();
                    }

                    if ( gateway != null )
                    {

                        string errorMessage = string.Empty;
                        var transaction = gateway.Charge( financialGateway, swipeInfo, out errorMessage );

                        if ( transaction != null )
                        {

                            var txnChanges = new List<string>();
                            txnChanges.Add( "Created Transaction (from kiosk)" );

                            _transactionCode = transaction.TransactionCode;
                            History.EvaluateChange( txnChanges, "Transaction Code", string.Empty, transaction.TransactionCode );

                            var personName = new PersonAliasService( rockContext )
                                .Queryable().AsNoTracking()
                                .Where( a => a.Id == this.SelectedGivingUnit.PersonAliasId )
                                .Select( a => a.Person.NickName + " " + a.Person.LastName )
                                .FirstOrDefault();

                            transaction.AuthorizedPersonAliasId = this.SelectedGivingUnit.PersonAliasId;
                            History.EvaluateChange( txnChanges, "Person", string.Empty, personName );

                            transaction.TransactionDateTime = RockDateTime.Now;
                            History.EvaluateChange( txnChanges, "Date/Time", null, transaction.TransactionDateTime );

                            transaction.FinancialGatewayId = financialGateway.Id;
                            History.EvaluateChange( txnChanges, "Gateway", string.Empty, financialGateway.Name );

                            var txnType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION ) );
                            transaction.TransactionTypeValueId = txnType.Id;
                            History.EvaluateChange( txnChanges, "Type", string.Empty, txnType.Value );

                            transaction.Summary = swipeInfo.Comment1;
                            History.EvaluateChange( txnChanges, "Transaction Code", string.Empty, transaction.Summary );

                            if ( transaction.FinancialPaymentDetail == null )
                            {
                                transaction.FinancialPaymentDetail = new FinancialPaymentDetail();
                            }
                            transaction.FinancialPaymentDetail.SetFromPaymentInfo( swipeInfo, gateway, rockContext, txnChanges );

                            Guid sourceGuid = Guid.Empty;
                            if ( Guid.TryParse( GetAttributeValue( "Source" ), out sourceGuid ) )
                            {
                                var source = DefinedValueCache.Read( sourceGuid );
                                if ( source != null )
                                {
                                    transaction.SourceTypeValueId = source.Id;
                                    History.EvaluateChange( txnChanges, "Source", string.Empty, source.Value );
                                }
                            }

                            foreach ( var accountAmount in this.Amounts.Where( a => a.Value > 0 ) )
                            {
                                var transactionDetail = new FinancialTransactionDetail();
                                transactionDetail.Amount = accountAmount.Value;
                                transactionDetail.AccountId = accountAmount.Key;
                                transaction.TransactionDetails.Add( transactionDetail );
                                var account = new FinancialAccountService( rockContext ).Get( accountAmount.Key );
                                if ( account != null )
                                {
                                    History.EvaluateChange( txnChanges, account.Name, 0.0M.FormatAsCurrency(), transactionDetail.Amount.FormatAsCurrency() );
                                }
                            }

                            var batchService = new FinancialBatchService( rockContext );

                            // Get the batch
                            var batch = batchService.Get(
                                GetAttributeValue( "BatchNamePrefix" ),
                                swipeInfo.CurrencyTypeValue,
                                swipeInfo.CreditCardTypeValue,
                                transaction.TransactionDateTime.Value,
                                financialGateway.GetBatchTimeOffset() );

                            var batchChanges = new List<string>();

                            if ( batch.Id == 0 )
                            {
                                batchChanges.Add( "Generated the batch" );
                                History.EvaluateChange( batchChanges, "Batch Name", string.Empty, batch.Name );
                                History.EvaluateChange( batchChanges, "Status", null, batch.Status );
                                History.EvaluateChange( batchChanges, "Start Date/Time", null, batch.BatchStartDateTime );
                                History.EvaluateChange( batchChanges, "End Date/Time", null, batch.BatchEndDateTime );
                            }

                            decimal newControlAmount = batch.ControlAmount + transaction.TotalAmount;
                            History.EvaluateChange( batchChanges, "Control Amount", batch.ControlAmount.FormatAsCurrency(), newControlAmount.FormatAsCurrency() );
                            batch.ControlAmount = newControlAmount;

                            transaction.BatchId = batch.Id;
                            batch.Transactions.Add( transaction );

                            rockContext.WrapTransaction( () =>
                            {

                                rockContext.SaveChanges();
                                HistoryService.SaveChanges(
                                    rockContext,
                                    typeof( FinancialBatch ),
                                    Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                    batch.Id,
                                    batchChanges
                                );

                                HistoryService.SaveChanges(
                                    rockContext,
                                    typeof( FinancialBatch ),
                                    Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(),
                                    batch.Id,
                                    txnChanges,
                                    personName,
                                    typeof( FinancialTransaction ),
                                    transaction.Id
                                );
                            } );

                            // send receipt in one is configured and not giving anonymously
                            if ( !string.IsNullOrWhiteSpace( GetAttributeValue( "ReceiptEmail" ) ) && ( this.AnonymousGiverPersonAliasId != this.SelectedGivingUnit.PersonAliasId ) )
                            {
                                _receiptSent = true;

                                SendReceipt();
                            }

                            HidePanels();
                            ShowReceiptPanel();
                        }
                        else
                        {
                            lSwipeErrors.Text = String.Format( "<div class='alert alert-danger'>An error occurred while process this transaction. Message: {0}</div>", errorMessage );
                        }

                    }
                    else
                    {
                        lSwipeErrors.Text = "<div class='alert alert-danger'>Invalid gateway provided. Please provide a gateway. Transaction not processed.</div>";
                    }
                }
            }
            catch ( Exception ex )
            {
                lSwipeErrors.Text = String.Format( "<div class='alert alert-danger'>An error occurred while process this transaction. Message: {0}</div>", ex.Message );
            }
        }
Exemple #30
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <exception cref="Exception">
        /// One or more exceptions occurred while downloading transactions..." + Environment.NewLine + exceptionMsgs.AsDelimited( Environment.NewLine )
        /// </exception>
        public virtual void Execute(IJobExecutionContext context)
        {
            var exceptionMsgs = new List <string>();

            // get the job map
            var dataMap = context.JobDetail.JobDataMap;
            var scheduledPaymentsProcessed = 0;

            Guid?receiptEmail              = dataMap.GetString(AttributeKey.ReceiptEmail).AsGuidOrNull();
            Guid?failedPaymentEmail        = dataMap.GetString(AttributeKey.FailedPaymentEmail).AsGuidOrNull();
            Guid?failedPaymentWorkflowType = dataMap.GetString(AttributeKey.FailedPaymentWorkflow).AsGuidOrNull();
            int  daysBack = dataMap.GetString(AttributeKey.DaysBack).AsIntegerOrNull() ?? 1;

            DateTime today            = RockDateTime.Today;
            TimeSpan daysBackTimeSpan = new TimeSpan(daysBack, 0, 0, 0);

            string batchNamePrefix = dataMap.GetString(AttributeKey.BatchNamePrefix);


            using (var rockContext = new RockContext())
            {
                var targetGatewayQuery = new FinancialGatewayService(rockContext).Queryable().Where(g => g.IsActive).AsNoTracking();

                var targetGatewayGuid = dataMap.GetString(AttributeKey.TargetGateway).AsGuidOrNull();
                if (targetGatewayGuid.HasValue)
                {
                    targetGatewayQuery = targetGatewayQuery.Where(g => g.Guid == targetGatewayGuid.Value);
                }

                foreach (var financialGateway in targetGatewayQuery.ToList())
                {
                    try
                    {
                        financialGateway.LoadAttributes(rockContext);

                        var gateway = financialGateway.GetGatewayComponent();
                        if (gateway == null)
                        {
                            continue;
                        }

                        DateTime endDateTime = today.Add(financialGateway.GetBatchTimeOffset());

                        // If the calculated end time has not yet occurred, use the previous day.
                        endDateTime = RockDateTime.Now.CompareTo(endDateTime) >= 0 ? endDateTime : endDateTime.AddDays(-1);

                        DateTime startDateTime = endDateTime.Subtract(daysBackTimeSpan);

                        string errorMessage = string.Empty;
                        var    payments     = gateway.GetPayments(financialGateway, startDateTime, endDateTime, out errorMessage);

                        if (string.IsNullOrWhiteSpace(errorMessage))
                        {
                            FinancialScheduledTransactionService.ProcessPayments(financialGateway, batchNamePrefix, payments, string.Empty, receiptEmail, failedPaymentEmail, failedPaymentWorkflowType);
                            scheduledPaymentsProcessed += payments.Count();
                        }
                        else
                        {
                            throw new Exception(errorMessage);
                        }
                    }
                    catch (Exception ex)
                    {
                        ExceptionLogService.LogException(ex, null);
                        exceptionMsgs.Add(ex.Message);
                    }
                }
            }

            if (exceptionMsgs.Any())
            {
                throw new Exception("One or more exceptions occurred while downloading transactions..." + Environment.NewLine + exceptionMsgs.AsDelimited(Environment.NewLine));
            }

            context.Result = string.Format("{0} payments processed", scheduledPaymentsProcessed);
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnInit( EventArgs e )
        {
            base.OnInit( e );

            if ( !Page.IsPostBack )
            {
                lPanelTitle1.Text = GetAttributeValue( "PanelTitle" );
                lPanelTitle2.Text = GetAttributeValue( "PanelTitle" );
                lContributionInfoTitle.Text = GetAttributeValue( "ContributionInfoTitle" );
                lPersonalInfoTitle.Text = GetAttributeValue( "PersonalInfoTitle" );
                lPaymentInfoTitle.Text = GetAttributeValue( "PaymentInfoTitle" );
                lConfirmationTitle.Text = GetAttributeValue( "ConfirmationTitle" );
                lSuccessTitle.Text = GetAttributeValue( "SuccessTitle" );
                lSaveAcccountTitle.Text = GetAttributeValue( "SaveAccountTitle" );
            }

            // Enable payment options based on the configured gateways
            bool ccEnabled = false;
            bool achEnabled = false;
            GatewayComponent ccGatewayComponent = null;
            GatewayComponent achGatewayComponent = null;
            var supportedFrequencies = new List<DefinedValueCache>();

            _showCommmentEntry = GetAttributeValue( "EnableCommentEntry" ).AsBoolean();
            txtCommentEntry.Label = GetAttributeValue( "CommentEntryLabel" );
            txtCommentEntry.Visible = _showCommmentEntry;

            using ( var rockContext = new RockContext() )
            {
                // If impersonation is allowed, and a valid person key was used, set the target to that person
                if ( GetAttributeValue( "Impersonation" ).AsBooleanOrNull() ?? false )
                {
                    string personKey = PageParameter( "Person" );
                    if ( !string.IsNullOrWhiteSpace( personKey ) )
                    {
                        TargetPerson = new PersonService( rockContext ).GetByUrlEncodedKey( personKey );
                    }
                }

                if ( TargetPerson == null )
                {
                    TargetPerson = CurrentPerson;
                }

                var financialGatewayService = new FinancialGatewayService( rockContext );
                Guid? ccGatewayGuid = GetAttributeValue( "CCGateway" ).AsGuidOrNull();
                if ( ccGatewayGuid.HasValue )
                {
                    _ccGateway = financialGatewayService.Get( ccGatewayGuid.Value );
                    if ( _ccGateway != null )
                    {
                        _ccGateway.LoadAttributes( rockContext );
                        ccGatewayComponent = _ccGateway.GetGatewayComponent();
                        if ( ccGatewayComponent != null )
                        {
                            ccEnabled = true;
                            txtCardFirstName.Visible = ccGatewayComponent.SplitNameOnCard;
                            txtCardLastName.Visible = ccGatewayComponent.SplitNameOnCard;
                            txtCardName.Visible = !ccGatewayComponent.SplitNameOnCard;
                            mypExpiration.MinimumYear = RockDateTime.Now.Year;
                        }
                    }
                }

                Guid? achGatewayGuid = GetAttributeValue( "ACHGateway" ).AsGuidOrNull();
                if ( achGatewayGuid.HasValue )
                {
                    _achGateway = financialGatewayService.Get( achGatewayGuid.Value );
                    if ( _achGateway != null )
                    {
                        _achGateway.LoadAttributes( rockContext );
                        achGatewayComponent = _achGateway.GetGatewayComponent();
                        achEnabled = achGatewayComponent != null;
                    }
                }
            }

            hfCurrentPage.Value = "1";
            RockPage page = Page as RockPage;
            if ( page != null )
            {
                page.PageNavigate += page_PageNavigate;
            }

            if ( ccEnabled || achEnabled )
            {
                if ( ccEnabled )
                {
                    supportedFrequencies = ccGatewayComponent.SupportedPaymentSchedules;
                    hfPaymentTab.Value = "CreditCard";
                }
                else
                {
                    supportedFrequencies = achGatewayComponent.SupportedPaymentSchedules;
                    hfPaymentTab.Value = "ACH";
                }

                if ( ccEnabled && achEnabled )
                {
                    phPills.Visible = true;

                    // If CC and ACH gateways are different, only allow frequencies supported by both payment gateways (if different)
                    if ( ccGatewayComponent.TypeId != _achGateway.TypeId )
                    {
                        supportedFrequencies = ccGatewayComponent.SupportedPaymentSchedules
                            .Where( c =>
                                achGatewayComponent.SupportedPaymentSchedules
                                    .Select( a => a.Id )
                                    .Contains( c.Id ) )
                            .ToList();
                    }

                    divCCPaymentInfo.AddCssClass( "tab-pane" );
                    divACHPaymentInfo.AddCssClass( "tab-pane" );
                }

                divCCPaymentInfo.Visible = ccEnabled;
                divACHPaymentInfo.Visible = achEnabled;

                if ( supportedFrequencies.Any() )
                {
                    bool allowScheduled = GetAttributeValue( "AllowScheduled" ).AsBoolean();
                    if ( allowScheduled )
                    {
                        _showRepeatingOptions = true;
                        var oneTimeFrequency = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME );
                        divRepeatingPayments.Visible = true;

                        btnFrequency.DataSource = supportedFrequencies;
                        btnFrequency.DataBind();

                        // If gateway didn't specifically support one-time, add it anyway for immediate gifts
                        if ( !supportedFrequencies.Where( f => f.Id == oneTimeFrequency.Id ).Any() )
                        {
                            btnFrequency.Items.Insert( 0, new ListItem( oneTimeFrequency.Value, oneTimeFrequency.Id.ToString() ) );
                        }

                        btnFrequency.SelectedValue = oneTimeFrequency.Id.ToString();
                        dtpStartDate.SelectedDate = RockDateTime.Today;
                    }
                }

                // Display Options
                btnAddAccount.Title = GetAttributeValue( "AddAccountText" );

                bool displayEmail = GetAttributeValue( "DisplayEmail" ).AsBoolean();
                txtEmail.Visible = displayEmail;
                tdEmailConfirm.Visible = displayEmail;
                tdEmailReceipt.Visible = displayEmail;

                bool displayPhone = GetAttributeValue( "DisplayPhone" ).AsBoolean();
                pnbPhone.Visible = displayPhone;
                tdPhoneConfirm.Visible = displayPhone;
                tdPhoneReceipt.Visible = displayPhone;

                FluidLayout = GetAttributeValue( "LayoutStyle" ) == "Fluid";

                BindSavedAccounts();

                if ( rblSavedCC.Items.Count > 0 )
                {
                    rblSavedCC.Items[0].Selected = true;
                    rblSavedCC.Visible = true;
                    divNewCard.Style[HtmlTextWriterStyle.Display] = "none";
                }
                else
                {
                    rblSavedCC.Visible = false;
                    divNewCard.Style[HtmlTextWriterStyle.Display] = "block";
                }

                if ( rblSavedAch.Items.Count > 0 )
                {
                    rblSavedAch.Items[0].Selected = true;
                    rblSavedAch.Visible = true;
                    divNewBank.Style[HtmlTextWriterStyle.Display] = "none";
                }
                else
                {
                    rblSavedAch.Visible = false;
                    divNewCard.Style[HtmlTextWriterStyle.Display] = "block";
                }

                RegisterScript();

                // Resolve the text field merge fields
                var configValues = new Dictionary<string, object>();
                phConfirmationHeader.Controls.Add( new LiteralControl( GetAttributeValue( "ConfirmationHeader" ).ResolveMergeFields( configValues ) ) );
                phConfirmationFooter.Controls.Add( new LiteralControl( GetAttributeValue( "ConfirmationFooter" ).ResolveMergeFields( configValues ) ) );
                phSuccessHeader.Controls.Add( new LiteralControl( GetAttributeValue( "SuccessHeader" ).ResolveMergeFields( configValues ) ) );
                phSuccessFooter.Controls.Add( new LiteralControl( GetAttributeValue( "SuccessFooter" ).ResolveMergeFields( configValues ) ) );

                //// Temp values for testing...
                /*
                txtCreditCard.Text = "5105105105105100";
                txtCVV.Text = "023";

                txtBankName.Text = "Test Bank";
                txtRoutingNumber.Text = "111111118";
                txtAccountNumber.Text = "1111111111";
                 */
            }
        }
Exemple #32
0
        /// <summary>
        /// Adds any registration templates given in the XML file.
        /// </summary>
        /// <param name="elemFamilies"></param>
        /// <param name="rockContext"></param>
        private void AddRegistrationTemplates( XElement elemRegistrationTemplates, RockContext rockContext )
        {
            if ( elemRegistrationTemplates == null )
            {
                return;
            }

            // Get attribute values from RegistrationTemplateDetail block
            // Get instance of the attribute.
            string defaultConfirmationEmail = string.Empty;
            string defaultReminderEmail = string.Empty;
            string defaultSuccessText = string.Empty;
            string defaultPaymentReminderEmail = string.Empty;

            //CodeEditorFieldAttribute MyAttribute = (CodeEditorFieldAttribute)System.Attribute.GetCustomAttribute( typeof( RockWeb.Blocks.Event.RegistrationTemplateDetail ), typeof( CodeEditorFieldAttribute ) );
            var blockAttributes = System.Attribute.GetCustomAttributes( typeof( RockWeb.Blocks.Event.RegistrationTemplateDetail ), typeof( CodeEditorFieldAttribute ) );
            foreach ( CodeEditorFieldAttribute blockAttribute in blockAttributes )
            {
                switch ( blockAttribute.Name )
                {
                    case "Default Confirmation Email":
                        defaultConfirmationEmail = blockAttribute.DefaultValue;
                        break;

                    case "Default Reminder Email":
                        defaultReminderEmail = blockAttribute.DefaultValue;
                        break;

                    case "Default Success Text":
                        defaultSuccessText = blockAttribute.DefaultValue;
                        break;

                    case "Default Payment Reminder Email":
                        defaultPaymentReminderEmail = blockAttribute.DefaultValue;
                        break;

                    default:
                        break;
                }
            }

            RegistrationTemplateService registrationTemplateService = new RegistrationTemplateService( rockContext );

            // Add a template for each...
            foreach ( var element in elemRegistrationTemplates.Elements( "registrationTemplate" ) )
            {
                // skip any illegally formatted items
                if ( element.Attribute( "guid" ) == null )
                {
                    continue;
                }

                int categoryId = CategoryCache.Read( element.Attribute( "categoryGuid" ).Value.Trim().AsGuid() ).Id;

                // Find the group type and
                var groupType = GroupTypeCache.Read( element.Attribute( "groupTypeGuid" ).Value.Trim().AsGuid() );

                RegistrantsSameFamily registrantsSameFamily;
                if ( element.Attribute( "registrantsInSameFamily" ) != null )
                {
                    Enum.TryParse( element.Attribute( "registrantsInSameFamily" ).Value.Trim(), out registrantsSameFamily );
                }
                else
                {
                    registrantsSameFamily = RegistrantsSameFamily.Ask;
                }

                bool setCostOnInstance = true;
                if ( element.Attribute( "setCostOn" ).Value.Trim() == "template" )
                {
                    setCostOnInstance = false;
                }

                RegistrationNotify notify = RegistrationNotify.None;
                RegistrationNotify matchNotify;
                foreach ( string item in element.Attribute( "notify" ).Value.SplitDelimitedValues( whitespace: false ) )
                {
                    if ( Enum.TryParse( item.Replace( " ", string.Empty ), out matchNotify ) )
                    {
                        notify = notify | matchNotify;
                    }
                }

                // Now find the matching financial gateway
                FinancialGatewayService financialGatewayService = new FinancialGatewayService( rockContext );
                string gatewayName = element.Attribute( "financialGateway" ) != null ? element.Attribute( "financialGateway" ).Value : "Test Gateway";
                var financialGateway = financialGatewayService.Queryable()
                    .Where( g => g.Name == gatewayName )
                    .FirstOrDefault();

                RegistrationTemplate registrationTemplate = new RegistrationTemplate()
                {
                    Guid = element.Attribute( "guid" ).Value.Trim().AsGuid(),
                    Name = element.Attribute( "name" ).Value.Trim(),
                    IsActive = true,
                    CategoryId = categoryId,
                    GroupTypeId = groupType.Id,
                    GroupMemberRoleId = groupType.DefaultGroupRoleId,
                    GroupMemberStatus = GroupMemberStatus.Active,
                    Notify = notify,
                    AddPersonNote = element.Attribute( "addPersonNote" ) != null ? element.Attribute( "addPersonNote" ).Value.AsBoolean() : false,
                    LoginRequired = element.Attribute( "loginRequired" ) != null ? element.Attribute( "loginRequired" ).Value.AsBoolean() : false,
                    AllowExternalRegistrationUpdates = element.Attribute( "allowExternalUpdatesToSavedRegistrations" ) != null ? element.Attribute( "allowExternalUpdatesToSavedRegistrations" ).Value.AsBoolean() : false,
                    AllowGroupPlacement = element.Attribute( "allowGroupPlacement" ) != null ? element.Attribute( "allowGroupPlacement" ).Value.AsBoolean() : false,
                    AllowMultipleRegistrants = element.Attribute( "allowMultipleRegistrants" ) != null ? element.Attribute( "allowMultipleRegistrants" ).Value.AsBoolean() : false,
                    MaxRegistrants = element.Attribute( "maxRegistrants" ).Value.AsInteger(),
                    RegistrantsSameFamily = registrantsSameFamily,
                    SetCostOnInstance = setCostOnInstance,
                    FinancialGatewayId = financialGateway.Id,
                    BatchNamePrefix = element.Attribute( "batchNamePrefix" ) != null ? element.Attribute( "batchNamePrefix" ).Value.Trim() : string.Empty,
                    Cost = element.Attribute( "cost" ).Value.AsDecimal(),
                    MinimumInitialPayment = element.Attribute( "minInitialPayment" ).Value.AsDecimal(),
                    RegistrationTerm = element.Attribute( "registrationTerm" ) != null ? element.Attribute( "registrationTerm" ).Value.Trim() : "Registration",
                    RegistrantTerm = element.Attribute( "registrantTerm" ) != null ? element.Attribute( "registrantTerm" ).Value.Trim() : "Registrant",
                    FeeTerm = element.Attribute( "feeTerm" ) != null ? element.Attribute( "feeTerm" ).Value.Trim() : "Additional Options",
                    DiscountCodeTerm = element.Attribute( "discountCodeTerm" ) != null ? element.Attribute( "discountCodeTerm" ).Value.Trim() : "Discount Code",
                    ConfirmationFromName = "{{ RegistrationInstance.ContactPersonAlias.Person.FullName }}",
                    ConfirmationFromEmail = "{{ RegistrationInstance.ContactEmail }}",
                    ConfirmationSubject = "{{ RegistrationInstance.Name }} Confirmation",
                    ConfirmationEmailTemplate = defaultConfirmationEmail,
                    ReminderFromName = "{{ RegistrationInstance.ContactPersonAlias.Person.FullName }}",
                    ReminderFromEmail = "{{ RegistrationInstance.ContactEmail }}",
                    ReminderSubject = "{{ RegistrationInstance.Name }} Reminder",
                    ReminderEmailTemplate = defaultReminderEmail,
                    SuccessTitle = "Congratulations {{ Registration.FirstName }}",
                    SuccessText = defaultSuccessText,
                    PaymentReminderEmailTemplate = defaultPaymentReminderEmail,
                    PaymentReminderFromEmail = "{{ RegistrationInstance.ContactEmail }}",
                    PaymentReminderFromName = "{{ RegistrationInstance.ContactPersonAlias.Person.FullName }}",
                    PaymentReminderSubject = "{{ RegistrationInstance.Name }} Payment Reminder",
                    PaymentReminderTimeSpan = element.Attribute( "paymentReminderTimeSpan" ) != null ? element.Attribute( "paymentReminderTimeSpan" ).Value.AsInteger() : 0,
                    CreatedDateTime = RockDateTime.Now,
                    ModifiedDateTime = RockDateTime.Now,
                };

                registrationTemplateService.Add( registrationTemplate );

                rockContext.SaveChanges();
                var x = registrationTemplate.Id;

                string name = element.Attribute( "name" ).Value.Trim();
                bool allowExternalUpdatesToSavedRegistrations = element.Attribute( "allowExternalUpdatesToSavedRegistrations" ).Value.AsBoolean();
                bool addPersonNote = element.Attribute( "addPersonNote" ).Value.AsBoolean();
                bool loginRequired = element.Attribute( "loginRequired" ).Value.AsBoolean();
                Guid guid = element.Attribute( "guid" ).Value.Trim().AsGuid();

                // Find any Form elements and add them to the template
                int formOrder = 0;
                var registrationAttributeQualifierColumn = "RegistrationTemplateId";
                int? registrationRegistrantEntityTypeId = EntityTypeCache.Read( typeof( Rock.Model.RegistrationRegistrant ) ).Id;
                if ( element.Elements( "forms" ).Count() > 0 )
                {
                    foreach ( var formElement in element.Elements( "forms" ).Elements( "form" ) )
                    {
                        formOrder++;
                        var form = new RegistrationTemplateForm();
                        form.Guid = formElement.Attribute( "guid" ).Value.Trim().AsGuid();
                        registrationTemplate.Forms.Add( form );
                        form.Name = formElement.Attribute( "name" ).Value.Trim();
                        form.Order = formOrder;

                        int ffOrder = 0;
                        if ( formElement.Elements( "formFields" ).Count() > 0 )
                        {
                            foreach ( var formFieldElement in formElement.Elements( "formFields" ).Elements( "field" ) )
                            {
                                ffOrder++;
                                var formField = new RegistrationTemplateFormField();
                                formField.Guid = Guid.NewGuid();
                                formField.CreatedDateTime = RockDateTime.Now;

                                form.Fields.Add( formField );

                                switch ( formFieldElement.Attribute( "source" ).Value.Trim().ToLowerInvariant() )
                                {
                                    case "person field":
                                        formField.FieldSource = RegistrationFieldSource.PersonField;
                                        break;
                                    case "person attribute":
                                        formField.FieldSource = RegistrationFieldSource.PersonAttribute;
                                        break;
                                    case "group member attribute":
                                        formField.FieldSource = RegistrationFieldSource.GroupMemberAttribute;
                                        break;
                                    case "registration attribute":
                                        formField.FieldSource = RegistrationFieldSource.RegistrationAttribute;

                                        //var qualifierValue = RegistrationTemplate.Id.ToString();
                                        var attrState = new Rock.Model.Attribute();

                                        attrState.Guid = formFieldElement.Attribute( "guid" ).Value.AsGuid();
                                        attrState.Name = formFieldElement.Attribute( "name" ).Value.Trim();
                                        attrState.Key = attrState.Name.RemoveSpecialCharacters().Replace( " ", string.Empty );
                                        var type = formFieldElement.Attribute( "type" ).Value.Trim();
                                        var fieldType = FieldTypeCache.All().Where( f => f.Name == type ).FirstOrDefault();
                                        attrState.FieldTypeId = fieldType.Id;
                                        var attribute = Helper.SaveAttributeEdits( attrState, registrationRegistrantEntityTypeId, registrationAttributeQualifierColumn, registrationTemplate.Id.ToString(), rockContext );
                                        //rockContext.ChangeTracker.DetectChanges();
                                        rockContext.SaveChanges( disablePrePostProcessing: true );
                                        formField.Attribute = attribute;

                                        break;
                                    default:
                                        throw new NotSupportedException( string.Format( "unknown form field source: {0}", formFieldElement.Attribute( "source" ).Value ) );
                                }

                                formField.AttributeId = null;
                                if ( !formField.AttributeId.HasValue &&
                                    formField.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                                    formField.Attribute != null )
                                {
                                    var attr = AttributeCache.Read( formField.Attribute.Guid, rockContext );
                                    if ( attr != null )
                                    {
                                        formField.AttributeId = attr.Id;
                                    }
                                }

                                RegistrationPersonFieldType registrationPersonFieldType;
                                if ( formField.FieldSource == RegistrationFieldSource.PersonField && formFieldElement.Attribute( "name" ) != null &&
                                    Enum.TryParse( formFieldElement.Attribute( "name" ).Value.Replace( " ", string.Empty ).Trim(), out registrationPersonFieldType ) )
                                {
                                    formField.PersonFieldType = registrationPersonFieldType;
                                }

                                formField.IsInternal = formFieldElement.Attribute( "isInternal" ) != null ? formFieldElement.Attribute( "isInternal" ).Value.AsBoolean() : false;
                                formField.IsSharedValue = formFieldElement.Attribute( "isCommon" ) != null ? formFieldElement.Attribute( "isCommon" ).Value.AsBoolean() : false;
                                formField.ShowCurrentValue = formFieldElement.Attribute( "showCurrentValue" ) != null ? formFieldElement.Attribute( "showCurrentValue" ).Value.AsBoolean() : false;
                                formField.PreText = formFieldElement.Attribute( "preText" ) != null ? formFieldElement.Attribute( "preText" ).Value : string.Empty;
                                formField.PostText = formFieldElement.Attribute( "postText" ) != null ? formFieldElement.Attribute( "postText" ).Value : string.Empty;
                                formField.IsGridField = formFieldElement.Attribute( "showOnGrid" ) != null ? formFieldElement.Attribute( "showOnGrid" ).Value.AsBoolean() : false;
                                formField.IsRequired = formFieldElement.Attribute( "isRequired" ) != null ? formFieldElement.Attribute( "isRequired" ).Value.AsBoolean() : false;
                                formField.Order = ffOrder;
                                formField.CreatedDateTime = RockDateTime.Now;
                            }
                        }
                    }
                }

                // Discounts
                int discountOrder = 0;
                if ( element.Elements( "discounts" ) != null )
                {
                    foreach ( var discountElement in element.Elements( "discounts" ).Elements( "discount" ) )
                    {
                        discountOrder++;
                        var discount = new RegistrationTemplateDiscount();
                        discount.Guid = Guid.NewGuid();
                        registrationTemplate.Discounts.Add( discount );

                        discount.Code = discountElement.Attribute( "code" ).Value;

                        switch ( discountElement.Attribute( "type" ).Value.Trim().ToLowerInvariant() )
                        {
                            case "percentage":
                                discount.DiscountPercentage = discountElement.Attribute( "value" ).Value.Trim().AsDecimal() * 0.01m;
                                discount.DiscountAmount = 0.0m;
                                break;
                            case "amount":
                                discount.DiscountPercentage = 0.0m;
                                discount.DiscountAmount = discountElement.Attribute( "value" ).Value.Trim().AsDecimal();
                                break;
                            default:
                                throw new NotSupportedException( string.Format( "unknown discount type: {0}", discountElement.Attribute( "type" ).Value ) );
                        }
                        discount.Order = discountOrder;
                    }
                }

                // Fees
                int feeOrder = 0;
                if ( element.Elements( "fees" ) != null )
                {
                    foreach ( var feeElement in element.Elements( "fees" ).Elements( "fee" ) )
                    {
                        feeOrder++;
                        var fee = new RegistrationTemplateFee();
                        fee.Guid = Guid.NewGuid();
                        registrationTemplate.Fees.Add( fee );

                        switch ( feeElement.Attribute( "type" ).Value.Trim().ToLowerInvariant() )
                        {
                            case "multiple":
                                fee.FeeType = RegistrationFeeType.Multiple;
                                fee.CostValue = FormatMultipleFeeCosts( feeElement.Elements( "option" ) );
                                break;
                            case "single":
                                fee.FeeType = RegistrationFeeType.Single;
                                fee.CostValue = feeElement.Attribute( "cost" ).Value.Trim();
                                break;
                            default:
                                throw new NotSupportedException( string.Format( "unknown fee type: {0}", feeElement.Attribute( "type" ).Value ) );
                        }

                        fee.Name = feeElement.Attribute( "name" ).Value.Trim();
                        fee.DiscountApplies = feeElement.Attribute( "discountApplies" ).Value.AsBoolean();
                        fee.AllowMultiple = feeElement.Attribute( "enableQuantity" ).Value.AsBoolean();
                        fee.Order = feeOrder;
                    }
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the btnMigrateSavedAccounts control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnMigrateSavedAccounts_Click(object sender, EventArgs e)
        {
            BinaryFile binaryFile        = null;
            var        rockContext       = new RockContext();
            var        binaryFileService = new BinaryFileService(rockContext);
            var        binaryFileId      = fuCustomerVaultImportFile.BinaryFileId;

            if (binaryFileId.HasValue)
            {
                binaryFile = binaryFileService.Get(binaryFileId.Value);
            }

            Dictionary <string, string> nmiToPiCustomerIdLookup = null;

            var importData = binaryFile.ContentsToString();

            StringReader stringReader = new StringReader(importData);
            CsvReader    csvReader    = new CsvReader(stringReader);

            csvReader.Configuration.HasHeaderRecord = false;

            nmiToPiCustomerIdLookup = csvReader.GetRecords <CustomerVaultImportRecord>().ToDictionary(k => k.NMICustomerId, v => v.PiCustomerId);

            var financialGatewayService = new FinancialGatewayService(rockContext);
            var nmiFinancialGatewayID   = ddlNMIGateway.SelectedValue.AsInteger();
            var nmiFinancialGateway     = financialGatewayService.Get(nmiFinancialGatewayID);
            var nmiGatewayComponent     = nmiFinancialGateway.GetGatewayComponent();
            var piFinancialGatewayId    = ddlPiGateway.SelectedValue.AsInteger();
            var piFinancialGateway      = financialGatewayService.Get(piFinancialGatewayId);
            var piGatewayComponent      = piFinancialGateway.GetGatewayComponent() as IHostedGatewayComponent;

            var financialPersonSavedAccountService = new FinancialPersonSavedAccountService(rockContext);
            var nmiPersonSavedAccountList          = financialPersonSavedAccountService.Queryable().Where(a => a.FinancialGatewayId == nmiFinancialGatewayID).ToList();

            var personSavedAccountResultsBuilder = new StringBuilder();

            var nmiPersonSavedAccountListCount = nmiPersonSavedAccountList.Count();

            foreach (var nmiPersonSavedAccount in nmiPersonSavedAccountList)
            {
                var nmiCustomerId = nmiPersonSavedAccount.GatewayPersonIdentifier ?? nmiPersonSavedAccount.ReferenceNumber;
                var piCustomerId  = nmiToPiCustomerIdLookup.GetValueOrNull(nmiCustomerId);

                nmiPersonSavedAccount.GatewayPersonIdentifier = piCustomerId;
                nmiPersonSavedAccount.FinancialGatewayId      = piFinancialGatewayId;

                // NOTE: NMI Customer IDs created after the Vault import file was created won't have a piCustomerId

                personSavedAccountResultsBuilder.AppendFormat(
                    "FinancialPersonSavedAccount.Id: {0} NMI CustomerId: '{1}', NMI GatewayPersonIdentifier: '{2}', NMI ReferenceNumber: '{3}', Pi CustomerId: '{4}'" + Environment.NewLine,
                    nmiPersonSavedAccount.Id,
                    nmiCustomerId,
                    nmiPersonSavedAccount.GatewayPersonIdentifier,
                    nmiPersonSavedAccount.ReferenceNumber,
                    piCustomerId
                    );
            }

            rockContext.SaveChanges();

            string resultSummary = string.Format("Migrated {0} Saved Accounts", nmiPersonSavedAccountList.Count());

            personSavedAccountResultsBuilder.AppendLine(resultSummary);

            if (!nmiPersonSavedAccountList.Any())
            {
                nbMigrateSavedAccounts.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Warning;
                nbMigrateSavedAccounts.Text = "No NMI Saved Accounts Found";
            }
            else
            {
                nbMigrateSavedAccounts.Title = "Success";
                nbMigrateSavedAccounts.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Success;
                nbMigrateSavedAccounts.Text = resultSummary;
            }

            nbMigrateSavedAccounts.Visible = true;
            nbMigrateSavedAccounts.Details = personSavedAccountResultsBuilder.ToString();
            this.SetBlockUserPreference("MigrateSavedAccountsResultSummary", nbMigrateSavedAccounts.Text);
            this.SetBlockUserPreference("MigrateSavedAccountsResultDetails", personSavedAccountResultsBuilder.ToString());
        }
Exemple #34
0
        private FinancialGateway GetFinancialGateway( FinancialGateway financialGateway, int? financialGatewayId)
        {
            if ( financialGateway != null )
            {
                if ( financialGateway.Attributes == null )
                {
                    financialGateway.LoadAttributes();
                }
                return financialGateway;
            }

            if ( financialGatewayId.HasValue )
            {
                using ( var rockContext = new RockContext() )
                {
                    var gateway = new FinancialGatewayService( rockContext ).Get( financialGatewayId.Value );
                    gateway.LoadAttributes( rockContext );
                    return gateway;
                }
            }

            return null;
        }
        public HttpResponseMessage Give( [FromBody]GiveParameters giveParameters )
        {
            var rockContext = new RockContext();

            try
            {
                rockContext.WrapTransaction( () =>
                {
                    int? locationId = null;
                    FinancialPaymentDetail paymentDetail = null;
                    PaymentInfo paymentInfo = null;
                    FinancialPersonSavedAccount savedAccount = null;
                    bool newSavedAccount = true;

                    var gatewayComponent = GatewayContainer.GetComponent( GATEWAY_NAME );

                    if ( gatewayComponent == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the gateway component" );
                    }

                    var financialGateway = new FinancialGatewayService( rockContext ).Queryable().FirstOrDefault( g => g.EntityTypeId == gatewayComponent.EntityType.Id );

                    if ( financialGateway == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the financial gateway" );
                    }

                    var totalAmount = CalculateTotalAmount( giveParameters, rockContext );
                    var person = GetExistingPerson( giveParameters.PersonId, rockContext );

                    if ( person == null )
                    {
                        // New person
                        locationId = CreateLocation( giveParameters, rockContext );
                        person = CreatePerson( giveParameters, locationId.Value, rockContext );
                    }
                    else
                    {
                        // Existing person
                        savedAccount = GetExistingSavedAccount( giveParameters, person, rockContext );

                        if ( savedAccount != null )
                        {
                            locationId = savedAccount.FinancialPaymentDetail.BillingLocationId;
                            newSavedAccount = false;
                        }
                    }

                    if ( !locationId.HasValue )
                    {
                        locationId = CreateLocation( giveParameters, rockContext );
                    }

                    if ( savedAccount == null )
                    {
                        paymentDetail = CreatePaymentDetail( giveParameters, person, locationId.Value, rockContext );
                        savedAccount = CreateSavedAccount( giveParameters, paymentDetail, financialGateway, person, rockContext );
                        newSavedAccount = true;
                        paymentInfo = GetPaymentInfo( giveParameters, person, rockContext, totalAmount.Value, paymentDetail );
                    }
                    else
                    {
                        paymentDetail = savedAccount.FinancialPaymentDetail;
                        locationId = paymentDetail.BillingLocationId;
                        paymentInfo = savedAccount.GetReferencePayment();
                        UpdatePaymentInfoForSavedAccount( giveParameters, paymentInfo, person, rockContext, locationId.Value, totalAmount.Value );
                    }

                    SaveLocationToFamilyIfNone( person, locationId.Value, rockContext );
                    string errorMessage;
                    var transaction = gatewayComponent.Charge( financialGateway, paymentInfo, out errorMessage );

                    if ( transaction == null || !string.IsNullOrWhiteSpace( errorMessage ) )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, errorMessage ?? "The gateway had a problem and/or did not create a transaction as expected" );
                    }

                    transaction.Batch = GetBatch( rockContext, financialGateway, giveParameters.AccountType );
                    transaction.FinancialPaymentDetail = null;
                    transaction.SourceTypeValueId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE ) ).Id;
                    transaction.TransactionDateTime = RockDateTime.Now;
                    transaction.AuthorizedPersonAliasId = person.PrimaryAliasId;
                    transaction.AuthorizedPersonAlias = person.PrimaryAlias;
                    transaction.FinancialGatewayId = financialGateway.Id;
                    transaction.TransactionTypeValueId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION ) ).Id;
                    transaction.FinancialPaymentDetailId = paymentDetail.Id;
                    savedAccount.TransactionCode = transaction.TransactionCode;

                    foreach ( var accountAmount in giveParameters.AmountDetails )
                    {
                        transaction.TransactionDetails.Add( new FinancialTransactionDetail()
                        {
                            Amount = accountAmount.Amount,
                            AccountId = accountAmount.TargetAccountId
                        } );
                    }

                    new FinancialTransactionService( rockContext ).Add( transaction );
                    rockContext.SaveChanges();

                    if ( newSavedAccount )
                    {
                        var newReferenceNumber = gatewayComponent.GetReferenceNumber( transaction, out errorMessage );
                        savedAccount.ReferenceNumber = newReferenceNumber;
                    }

                    rockContext.SaveChanges();
                } );
            }
            catch ( HttpResponseException exception )
            {
                return exception.Response;
            }
            catch ( Exception exception )
            {
                var response = new HttpResponseMessage( HttpStatusCode.InternalServerError );
                response.Content = new StringContent( exception.Message );
                return response;
            }

            return new HttpResponseMessage( HttpStatusCode.NoContent );
        }
        private FinancialGateway GetSelectedGateway()
        {
            int? gatewayId = gpGateway.SelectedValueAsInt();
            if ( gatewayId.HasValue )
            {
                using ( var rockContext = new RockContext() )
                {
                    var financialGateway = new FinancialGatewayService( rockContext ).Get( gatewayId.Value );
                    if ( financialGateway != null )
                    {
                        financialGateway.LoadAttributes( rockContext );
                        return financialGateway;
                    }
                }
            }

            return null;
        }
        public HttpResponseMessage StopScheduledGiving( int id )
        {
            var rockContext = new RockContext();
            try
            {
                rockContext.WrapTransaction( () =>
                {
                    var gatewayComponent = GatewayContainer.GetComponent( GATEWAY_NAME );

                    if ( gatewayComponent == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the gateway component" );
                    }

                    var financialGateway = new FinancialGatewayService( rockContext ).Queryable().FirstOrDefault( g => g.EntityTypeId == gatewayComponent.EntityType.Id );

                    if ( financialGateway == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the financial gateway" );
                    }

                    var schedule = ( new FinancialScheduledTransactionService( rockContext ) ).Get( id );

                    if ( schedule == null )
                    {
                        GenerateResponse( HttpStatusCode.BadRequest, "No schedule with Id: " + id );
                    }

                    string errorMessage;
                    var error = gatewayComponent.CancelScheduledPayment( schedule, out errorMessage );

                    if ( error || errorMessage != null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, errorMessage ?? "There was an error with the gateway" );
                    }

                    schedule.IsActive = false;
                    rockContext.SaveChanges();
                } );
            }
            catch ( HttpResponseException exception )
            {
                return exception.Response;
            }
            catch ( Exception exception )
            {
                var response = new HttpResponseMessage( HttpStatusCode.InternalServerError );
                response.Content = new StringContent( exception.Message );
                return response;
            }

            return new HttpResponseMessage( HttpStatusCode.OK );
        }
        public HttpResponseMessage ScheduleGiving( [FromBody]ScheduleParameters scheduleParameters )
        {
            var rockContext = new RockContext();

            try
            {
                rockContext.WrapTransaction( () =>
                {
                    var person = GetExistingPerson( scheduleParameters.PersonId, rockContext );

                    if ( person == null )
                    {
                        GenerateResponse( HttpStatusCode.BadRequest, "An existing person is required to schedule giving" );
                    }

                    var totalAmount = CalculateTotalAmount( scheduleParameters, rockContext );
                    var paymentSchedule = GetPaymentSchedule( scheduleParameters, person);
                    var gatewayComponent = GatewayContainer.GetComponent( GATEWAY_NAME );

                    if ( gatewayComponent == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the gateway component" );
                    }

                    var financialGateway = new FinancialGatewayService( rockContext ).Queryable().FirstOrDefault( g => g.EntityTypeId == gatewayComponent.EntityType.Id );

                    if ( financialGateway == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the financial gateway" );
                    }

                    var savedAccount = GetExistingSavedAccount( scheduleParameters, person, rockContext );
                    FinancialPaymentDetail paymentDetail = null;
                    PaymentInfo paymentInfo = null;
                    int? locationId = null;

                    if ( savedAccount == null )
                    {
                        locationId = CreateLocation( scheduleParameters, rockContext );
                        paymentDetail = CreatePaymentDetail( scheduleParameters, person, locationId.Value, rockContext );
                        savedAccount = CreateSavedAccount( scheduleParameters, paymentDetail, financialGateway, person, rockContext );
                        paymentInfo = GetPaymentInfo( scheduleParameters, person, rockContext, totalAmount.Value, paymentDetail );
                    }
                    else
                    {
                        paymentDetail = savedAccount.FinancialPaymentDetail;
                        locationId = paymentDetail.BillingLocationId;
                        paymentInfo = savedAccount.GetReferencePayment();
                        UpdatePaymentInfoForSavedAccount(scheduleParameters, paymentInfo, person, rockContext, paymentDetail.BillingLocationId.Value, totalAmount.Value);
                    }

                    SaveLocationToFamilyIfNone( person, locationId.Value, rockContext );
                    string errorMessage;
                    var schedule = gatewayComponent.AddScheduledPayment( financialGateway, paymentSchedule, paymentInfo, out errorMessage );

                    if ( schedule == null || !string.IsNullOrWhiteSpace( errorMessage ) )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, errorMessage ?? "The gateway had a problem and/or did not create a transaction as expected" );
                    }

                    schedule.TransactionFrequencyValueId = paymentSchedule.TransactionFrequencyValue.Id;

                    if ( person.PrimaryAliasId.HasValue )
                    {
                        schedule.AuthorizedPersonAliasId = person.PrimaryAliasId.Value;
                    }

                    schedule.FinancialPaymentDetail = paymentDetail;
                    schedule.FinancialPaymentDetail.CurrencyTypeValueId = paymentInfo.CurrencyTypeValue.Id;

                    if ( paymentInfo.CreditCardTypeValue != null )
                    {
                        schedule.FinancialPaymentDetail.CreditCardTypeValueId = paymentInfo.CreditCardTypeValue.Id;
                    }

                    foreach ( var accountAmount in scheduleParameters.AmountDetails )
                    {
                        schedule.ScheduledTransactionDetails.Add( new FinancialScheduledTransactionDetail()
                        {
                            Amount = accountAmount.Amount,
                            AccountId = accountAmount.TargetAccountId
                        } );
                    }

                    new FinancialScheduledTransactionService( rockContext ).Add( schedule );
                    rockContext.SaveChanges();
                } );
            }
            catch ( HttpResponseException exception )
            {
                return exception.Response;
            }
            catch ( Exception exception )
            {
                var response = new HttpResponseMessage( HttpStatusCode.InternalServerError );
                response.Content = new StringContent( exception.Message );
                return response;
            }

            return new HttpResponseMessage( HttpStatusCode.NoContent );
        }
        public HttpResponseMessage SavePaymentAccount( [FromBody]PaymentParameters paymentParameters )
        {
            var rockContext = new RockContext();
            try
            {
                rockContext.WrapTransaction( () =>
                {
                    var person = GetExistingPerson( paymentParameters.PersonId, rockContext );

                    if ( person == null )
                    {
                        GenerateResponse( HttpStatusCode.BadRequest, "An existing person is required to save a payment" );
                    }

                    var gatewayComponent = GatewayContainer.GetComponent( GATEWAY_NAME );

                    if ( gatewayComponent == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the gateway component" );
                    }

                    var financialGateway = new FinancialGatewayService( rockContext ).Queryable().FirstOrDefault( g => g.EntityTypeId == gatewayComponent.EntityType.Id );

                    if ( financialGateway == null )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, "There was a problem creating the financial gateway" );
                    }

                    var locationId = CreateLocation( paymentParameters, rockContext );
                    var paymentDetail = CreatePaymentDetail( paymentParameters, person, locationId, rockContext );
                    var savedAccount = CreateSavedAccount( paymentParameters, paymentDetail, financialGateway, person, rockContext );
                    var paymentInfo = GetPaymentInfo( paymentParameters, person, rockContext, 0, paymentDetail );

                    string errorMessage;
                    var transaction = gatewayComponent.Authorize( financialGateway, paymentInfo, out errorMessage );

                    if ( transaction == null || !string.IsNullOrWhiteSpace( errorMessage ) )
                    {
                        GenerateResponse( HttpStatusCode.InternalServerError, errorMessage ?? "The gateway had a problem and/or did not create a transaction as expected" );
                    }

                    transaction.Batch = GetBatch(rockContext, financialGateway, paymentParameters.AccountType);
                    transaction.FinancialPaymentDetail = null;
                    transaction.SourceTypeValueId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE ) ).Id;
                    transaction.TransactionDateTime = RockDateTime.Now;
                    transaction.AuthorizedPersonAliasId = person.PrimaryAliasId;
                    transaction.AuthorizedPersonAlias = person.PrimaryAlias;
                    transaction.FinancialGateway = financialGateway;
                    transaction.FinancialGatewayId = financialGateway.Id;
                    transaction.TransactionTypeValueId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION ) ).Id;
                    transaction.FinancialPaymentDetailId = paymentDetail.Id;

                    savedAccount.TransactionCode = transaction.TransactionCode;
                    SaveLocationToFamilyIfNone(person, locationId, rockContext);
                    savedAccount.ReferenceNumber = gatewayComponent.GetReferenceNumber( transaction, out errorMessage );
                    rockContext.SaveChanges();
                } );
            }
            catch ( HttpResponseException exception )
            {
                return exception.Response;
            }
            catch ( Exception exception )
            {
                var response = new HttpResponseMessage( HttpStatusCode.InternalServerError );
                response.Content = new StringContent( exception.Message );
                return response;
            }

            return new HttpResponseMessage( HttpStatusCode.NoContent );
        }
 /// <summary>
 /// Reads new values entered by the user for the field
 /// </summary>
 /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
 /// <param name="configurationValues"></param>
 /// <returns></returns>
 public override string GetEditValue( Control control, Dictionary<string, ConfigurationValue> configurationValues )
 {
     if ( control != null && control is FinancialGatewayPicker )
     {
         int id = int.MinValue;
         if ( Int32.TryParse( ( (FinancialGatewayPicker)control ).SelectedValue, out id ) )
         {
             using ( var rockContext = new RockContext() )
             {
                 var financialGateway = new FinancialGatewayService( rockContext ).Get( id );
                 if ( financialGateway != null )
                 {
                     return financialGateway.Guid.ToString();
                 }
             }
         }
     }
     return null;
 }
 private FinancialGateway GetGateway( RockContext rockContext, string attributeName )
 {
     var financialGatewayService = new FinancialGatewayService( rockContext );
     Guid? ccGatewayGuid = GetAttributeValue( attributeName ).AsGuidOrNull();
     if ( ccGatewayGuid.HasValue )
     {
         return financialGatewayService.Get( ccGatewayGuid.Value );
     }
     return null;
 }
 /// <summary>
 /// Sets the value.
 /// </summary>
 /// <param name="control">The control.</param>
 /// <param name="configurationValues"></param>
 /// <param name="value">The value.</param>
 public override void SetEditValue( Control control, Dictionary<string, ConfigurationValue> configurationValues, string value )
 {
     Guid financialGatewayGuid = Guid.Empty;
     if (Guid.TryParse( value, out financialGatewayGuid ))
     {
         if ( control != null && control is FinancialGatewayPicker )
         {
             using ( var rockContext = new RockContext() )
             {
                 var financialGateway = new FinancialGatewayService( rockContext ).Get( financialGatewayGuid );
                 if ( financialGateway != null )
                 {
                     ( (FinancialGatewayPicker)control ).SetValue( financialGateway.Id.ToString() );
                 }
             }
         }
     }
 }
Exemple #43
0
        /// <summary>
        /// Binds the Gateway list grid.
        /// </summary>
        private void BindGrid()
        {
            using ( var rockContext = new RockContext() )
            {
                var qry = new FinancialGatewayService( rockContext )
                    .Queryable( "EntityType" ).AsNoTracking();

                SortProperty sortProperty = rGridGateway.SortProperty;
                if ( sortProperty != null )
                {
                    qry = qry.Sort( sortProperty );
                }
                else
                {
                    qry = qry.OrderBy( g => g.Name );
                }

                rGridGateway.DataSource = qry.ToList();
                rGridGateway.DataBind();
            }
        }
Exemple #44
0
        /// <summary>
        /// Handles the Delete event of the rGridGateway control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void rGridGateway_Delete( object sender, RowEventArgs e )
        {
            var rockContext = new RockContext();
            var gatewayService = new FinancialGatewayService( rockContext );
            var gateway = gatewayService.Get( e.RowKeyId );
            if ( gateway != null )
            {
                string errorMessage;
                if ( !gatewayService.CanDelete( gateway, out errorMessage ) )
                {
                    mdGridWarning.Show( errorMessage, ModalAlertType.Information );
                    return;
                }

                gatewayService.Delete( gateway );
                rockContext.SaveChanges();
            }

            BindGrid();
        }
Exemple #45
0
        /// <summary>
        /// Handles the Click event of the btnGive control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnGive_Click(object sender, EventArgs e)
        {
            Person person = FindPerson();

            using (new UnitOfWorkScope())
            {
                RockTransactionScope.WrapTransaction(() =>
                {
                    var groupLocationService = new GroupLocationService();
                    var groupMemberService   = new GroupMemberService();
                    var phoneService         = new PhoneNumberService();
                    var locationService      = new LocationService();
                    var groupService         = new GroupService();
                    GroupLocation groupLocation;
                    Location homeAddress;
                    Group familyGroup;

                    var homeLocationType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_HOME);
                    var addressList      = locationService.Queryable().Where(l => l.Street1 == txtStreet.Text &&
                                                                             l.City == txtCity.Text && l.State == ddlState.SelectedValue && l.Zip == txtZip.Text &&
                                                                             l.LocationTypeValueId == homeLocationType.Id).ToList();

                    if (!addressList.Any())
                    {
                        homeAddress = new Location();
                        locationService.Add(homeAddress, person.Id);
                    }
                    else
                    {
                        homeAddress = addressList.FirstOrDefault();
                    }

                    homeAddress.Street1             = txtStreet.Text ?? homeAddress.Street1;
                    homeAddress.City                = txtCity.Text ?? homeAddress.City;
                    homeAddress.State               = ddlState.SelectedValue ?? homeAddress.State;
                    homeAddress.Zip                 = txtZip.Text ?? homeAddress.Zip;
                    homeAddress.IsActive            = true;
                    homeAddress.IsLocation          = true;
                    homeAddress.Country             = "US";
                    homeAddress.LocationTypeValueId = homeLocationType.Id;
                    locationService.Save(homeAddress, person.Id);

                    GroupType familyGroupType = new GroupTypeService().Get(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY));
                    var familyGroupList       = groupMemberService.Queryable().Where(g => g.PersonId == person.Id &&
                                                                                     g.Group.GroupType.Guid == familyGroupType.Guid).Select(g => g.Group).ToList();

                    if (!familyGroupList.Any())
                    {
                        familyGroup                = new Group();
                        familyGroup.IsActive       = true;
                        familyGroup.IsSystem       = false;
                        familyGroup.IsSecurityRole = false;
                        familyGroup.Name           = "The " + txtLastName.Text + " Family";
                        familyGroup.GroupTypeId    = familyGroupType.Id;
                        groupService.Add(familyGroup, person.Id);
                        groupService.Save(familyGroup, person.Id);

                        var familyMember         = new GroupMember();
                        familyMember.IsSystem    = false;
                        familyMember.GroupId     = familyGroup.Id;
                        familyMember.PersonId    = person.Id;
                        familyMember.GroupRoleId = new GroupRoleService().Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)).Id;
                        groupMemberService.Add(familyMember, person.Id);
                        groupMemberService.Save(familyMember, person.Id);
                    }
                    else
                    {
                        familyGroup = familyGroupList.FirstOrDefault();
                    }

                    var groupLocationList = groupLocationService.Queryable().Where(g => g.GroupLocationTypeValueId == familyGroupType.Id &&
                                                                                   g.GroupId == familyGroup.Id).ToList();

                    if (!groupLocationList.Any())
                    {
                        groupLocation            = new GroupLocation();
                        groupLocation.GroupId    = familyGroup.Id;
                        groupLocation.LocationId = homeAddress.Id;
                        groupLocation.IsMailing  = true;
                        groupLocation.IsLocation = true;
                        groupLocation.GroupLocationTypeValueId = homeLocationType.Id;
                        groupLocationService.Add(groupLocation, person.Id);
                        groupLocationService.Save(groupLocation, person.Id);
                    }
                    else
                    {
                        groupLocation = groupLocationList.FirstOrDefault();
                    }

                    groupLocation.LocationId = homeAddress.Id;
                    groupLocationService.Save(groupLocation, person.Id);

                    var homePhoneType   = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME);
                    string phoneNumeric = txtPhone.Text.AsNumeric();
                    if (!phoneService.Queryable().Where(n => n.PersonId == person.Id &&
                                                        n.NumberTypeValueId == homePhoneType.Id && n.Number == phoneNumeric).Any())
                    {
                        var homePhone                = new PhoneNumber();
                        homePhone.Number             = phoneNumeric;
                        homePhone.PersonId           = person.Id;
                        homePhone.IsSystem           = false;
                        homePhone.IsMessagingEnabled = false;
                        homePhone.IsUnlisted         = false;
                        homePhone.NumberTypeValueId  = homePhoneType.Id;
                        phoneService.Add(homePhone, person.Id);
                        phoneService.Save(homePhone, person.Id);
                    }
                });
            }

            var      amountList   = (Dictionary <FinancialAccount, Decimal>)Session["CachedAmounts"];
            var      profileId    = (int)Session["CachedProfileId"];
            Location giftLocation = new Location();

            var configValues = (Dictionary <string, object>)Session["CachedMergeFields"];

            configValues.Add("Date", DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm tt"));

            var receiptTemplate = GetAttributeValue("ReceiptMessage");

            lReceipt.Text = receiptTemplate.ResolveMergeFields(configValues);
            var    summaryTemplate = GetAttributeValue("SummaryMessage");
            string summaryMessage  = summaryTemplate.ResolveMergeFields(configValues);

            var creditProcessorId = GetAttributeValue("CreditCardProvider");
            var achProcessorId    = GetAttributeValue("Checking/ACHProvider");
            var gatewayService    = new FinancialGatewayService();
            FinancialGateway gateway;

            if (!string.IsNullOrEmpty(txtCreditCard.Text) && !string.IsNullOrWhiteSpace(creditProcessorId))
            {
                int creditId = Convert.ToInt32(creditProcessorId);
                gateway = new FinancialGatewayService().Get(creditId);
            }
            else if (!string.IsNullOrEmpty(txtAccountNumber.Text) && !string.IsNullOrWhiteSpace(achProcessorId))
            {
                int achId = Convert.ToInt32(achProcessorId);
                gateway = new FinancialGatewayService().Get(achId);
            }
            else
            {
                gateway = gatewayService.Queryable().FirstOrDefault();
            }

            // #TODO test card through gateway

            if (btnFrequency.SelectedIndex > -1 && btnFrequency.SelectedValueAsInt() != DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_TYPE_ONE_TIME).Id)
            {
                using (new UnitOfWorkScope())
                {
                    RockTransactionScope.WrapTransaction(() =>
                    {
                        var scheduledTransactionDetailService = new FinancialScheduledTransactionDetailService();
                        var scheduledTransactionService       = new FinancialScheduledTransactionService();
                        FinancialScheduledTransaction scheduledTransaction;
                        var detailList = amountList.ToList();

                        if (profileId > 0)
                        {
                            scheduledTransaction = scheduledTransactionService.Get(profileId);
                        }
                        else
                        {
                            scheduledTransaction = new FinancialScheduledTransaction();
                            scheduledTransactionService.Add(scheduledTransaction, person.Id);
                        }

                        DateTime startDate = (DateTime)dtpStartDate.SelectedDate;
                        if (startDate != null)
                        {
                            scheduledTransaction.StartDate = startDate;
                        }

                        scheduledTransaction.TransactionFrequencyValueId = (int)btnFrequency.SelectedValueAsInt();
                        scheduledTransaction.AuthorizedPersonId          = person.Id;
                        scheduledTransaction.IsActive = true;

                        if (!string.IsNullOrEmpty(txtCreditCard.Text))
                        {
                            scheduledTransaction.CardReminderDate = mypExpiration.SelectedDate;
                        }

                        if (chkLimitGifts.Checked && !string.IsNullOrWhiteSpace(txtLimitNumber.Text))
                        {
                            scheduledTransaction.NumberOfPayments = Convert.ToInt32(txtLimitNumber.Text);
                        }

                        foreach (var detail in amountList.ToList())
                        {
                            var scheduledTransactionDetail       = new FinancialScheduledTransactionDetail();
                            scheduledTransactionDetail.AccountId = detail.Key.Id;
                            scheduledTransactionDetail.Amount    = detail.Value;
                            scheduledTransactionDetail.ScheduledTransactionId = scheduledTransaction.Id;
                            scheduledTransactionDetailService.Add(scheduledTransactionDetail, person.Id);
                            scheduledTransactionDetailService.Save(scheduledTransactionDetail, person.Id);
                        }

                        // implement gateway charge()

                        scheduledTransactionService.Save(scheduledTransaction, person.Id);
                    });
                }
            }
            else
            {
                using (new UnitOfWorkScope())
                {
                    RockTransactionScope.WrapTransaction(() =>
                    {
                        var transactionService = new FinancialTransactionService();
                        var tdService          = new FinancialTransactionDetailService();
                        var transaction        = new FinancialTransaction();
                        var detailList         = amountList.ToList();

                        transaction.Summary = summaryMessage;
                        transaction.Amount  = detailList.Sum(d => d.Value);
                        transaction.TransactionTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION).Id;
                        transaction.TransactionDateTime    = DateTimeOffset.Now.DateTime;
                        transaction.AuthorizedPersonId     = person.Id;
                        transactionService.Add(transaction, person.Id);

                        foreach (var detail in detailList)
                        {
                            var td           = new FinancialTransactionDetail();
                            td.TransactionId = transaction.Id;
                            td.AccountId     = detail.Key.Id;
                            td.Amount        = detail.Value;
                            td.TransactionId = transaction.Id;
                            tdService.Add(td, person.Id);
                            tdService.Save(td, person.Id);
                        }

                        // #TODO implement gateway.charge()

                        transactionService.Save(transaction, person.Id);
                    });
                }
            }

            Session["CachedMergeFields"] = configValues;
            pnlConfirm.Visible           = false;
            pnlComplete.Visible          = true;
            pnlContribution.Update();
        }
        /// <summary>
        /// Handles the Click event of the btnMigrateScheduledTransactions control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnMigrateScheduledTransactions_Click(object sender, EventArgs e)
        {
            var rockContext = new RockContext();

            var binaryFileService = new BinaryFileService(rockContext);
            var binaryFileId      = fuScheduleImportFile.BinaryFileId;

            BinaryFile binaryFile = null;

            if (binaryFileId.HasValue)
            {
                binaryFile = binaryFileService.Get(binaryFileId.Value);
            }

            Dictionary <string, string> subscriptionImportRecordLookup = null;

            var importData = binaryFile.ContentsToString();

            StringReader stringReader = new StringReader(importData);
            CsvReader    csvReader    = new CsvReader(stringReader);

            csvReader.Configuration.HasHeaderRecord = false;

            subscriptionImportRecordLookup = csvReader.GetRecords <SubscriptionCustomerImportRecord>().ToDictionary(k => k.NMISubscriptionId, v => v.PiCustomerId);

            var financialGatewayService = new FinancialGatewayService(rockContext);
            var nmiFinancialGatewayId   = ddlNMIGateway.SelectedValue.AsInteger();
            var nmiFinancialGateway     = financialGatewayService.Get(nmiFinancialGatewayId);
            var nmiGatewayComponent     = nmiFinancialGateway.GetGatewayComponent();
            var piFinancialGatewayId    = ddlPiGateway.SelectedValue.AsInteger();
            var piFinancialGateway      = financialGatewayService.Get(piFinancialGatewayId);
            var piGatewayComponent      = piFinancialGateway.GetGatewayComponent() as IHostedGatewayComponent;

            var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext);

            // Get the ScheduledTransaction with NoTracking. If we need to update it, we'll track it with a different rockContext then save it.
            // Limit to active subscriptions that have a NextPaymentDate (onetime or canceled schedules might not have a NextPaymentDate)
            var scheduledTransactions = financialScheduledTransactionService.Queryable().Where(a => a.FinancialGatewayId == nmiFinancialGatewayId & a.IsActive && a.NextPaymentDate.HasValue).AsNoTracking().ToList();

            var earliestPiStartDate = piGatewayComponent.GetEarliestScheduledStartDate(piFinancialGateway);
            var oneTimeFrequencyId  = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid());

            string errorMessage;

            var scheduledTransactionResultsBuilder = new StringBuilder();

            var scheduledTransactionCount    = scheduledTransactions.Count();
            var scheduledTransactionProgress = 0;

            // Migrating Scheduled Transactions might take a while. Each migrated Scheduled Payment may take a half second or so to create on the Pi Gateway.
            var importTask = new Task(() =>
            {
                // wait a little so the browser can render and start listening to events
                Task.Delay(1000).Wait();
                _hubContext.Clients.All.setButtonVisibilty(this.SignalRNotificationKey, false);

                foreach (var scheduledTransaction in scheduledTransactions)
                {
                    System.Threading.Thread.Sleep(1000);

                    UpdateProgressMessage(string.Format("Migrating Scheduled Transactions: {0} of {1}", scheduledTransactionProgress, scheduledTransactionCount), " ");

                    scheduledTransactionProgress++;
                    var nmiSubscriptionId = scheduledTransaction.GatewayScheduleId;
                    var nmiCustomerId     = scheduledTransaction.ForeignKey;
                    var piCustomerId      = subscriptionImportRecordLookup.GetValueOrNull(nmiSubscriptionId);
                    if (piCustomerId == null)
                    {
                        scheduledTransactionResultsBuilder.AppendFormat(
                            "WARNING: No Pi CustomerId found for Financial Scheduled Transaction with Id: {0} which is associated NMI SubscriptionId: '{1}'" + Environment.NewLine,
                            scheduledTransaction.Id,
                            nmiSubscriptionId
                            );
                        continue;
                    }

                    // Pi requires that NextPaymentDate is in the Future (using UTC). That math is done in the gateway implementation...
                    // if the NextPayment null or earlier than whatever Pi considers the earliest start date, see if we can fix that up by calling GetStatus
                    if (scheduledTransaction.NextPaymentDate == null || scheduledTransaction.NextPaymentDate < earliestPiStartDate)
                    {
                        financialScheduledTransactionService.GetStatus(scheduledTransaction, out errorMessage);
                    }

                    if (scheduledTransaction.NextPaymentDate == null)
                    {
                        // Shouldn't happen, but just in case
                        scheduledTransactionResultsBuilder.AppendFormat(
                            "WARNING: Unknown NextPaymentDate for FinancialScheduledTransaction.Id: {0} NMI SubscriptionId: '{1}'" + Environment.NewLine,
                            scheduledTransaction.Id,
                            nmiSubscriptionId
                            );
                        continue;
                    }


                    if (scheduledTransaction.NextPaymentDate < earliestPiStartDate)
                    {
                        if ((scheduledTransaction.NextPaymentDate > RockDateTime.Today) && earliestPiStartDate.Subtract(scheduledTransaction.NextPaymentDate.Value).TotalDays <= 2)
                        {
                            // if the NextPaymentDate is after Today but before the Earliest Pi Start Date, it'll be off by less than 24 hrs, so just reschedule it for the Earliest Pi Start Date
                            scheduledTransaction.NextPaymentDate = earliestPiStartDate;
                        }
                        else
                        {
                            // if the NextPaymentDate is still too early AFTER getting the most recent status, then we can't safely figure it out, so report it
                            scheduledTransactionResultsBuilder.AppendFormat(
                                "WARNING: NextPaymentDate of {0} for FinancialScheduledTransaction.Id: {1} and NMI SubscriptionId: '{2}' must have a NextPaymentDate of at least {3}." + Environment.NewLine,
                                scheduledTransaction.NextPaymentDate,
                                scheduledTransaction.Id,
                                nmiSubscriptionId,
                                earliestPiStartDate
                                );
                        }
                    }

                    // create a subscription in the Pi System, then cancel the one on the NMI system
                    PaymentSchedule paymentSchedule = new PaymentSchedule
                    {
                        TransactionFrequencyValue = DefinedValueCache.Get(scheduledTransaction.TransactionFrequencyValueId),
                        StartDate = scheduledTransaction.NextPaymentDate.Value,
                        PersonId  = scheduledTransaction.AuthorizedPersonAlias.PersonId
                    };

                    ReferencePaymentInfo referencePaymentInfo = new ReferencePaymentInfo
                    {
                        GatewayPersonIdentifier = piCustomerId,
                        Description             = string.Format("Migrated from NMI SubscriptionID:{0}", nmiSubscriptionId)
                    };

                    var piGateway = (piGatewayComponent as PiGateway);
                    string alreadyMigratedPiSubscriptionId = null;

                    if (piGateway != null)
                    {
                        var customerPiSubscriptions     = piGateway.SearchCustomerSubscriptions(piFinancialGateway, piCustomerId);
                        alreadyMigratedPiSubscriptionId = customerPiSubscriptions.Data.Where(a => a.Description.Contains(referencePaymentInfo.Description)).Select(a => a.Customer.Id).FirstOrDefault();
                    }

                    if (string.IsNullOrEmpty(alreadyMigratedPiSubscriptionId))
                    {
                        // hasn't already been migrated, so go ahead and migrate it
                        var tempFinancialScheduledTransaction = piGatewayComponent.AddScheduledPayment(piFinancialGateway, paymentSchedule, referencePaymentInfo, out errorMessage);
                        if (tempFinancialScheduledTransaction != null)
                        {
                            ////////////#### DISABLE this when debugger #####
                            nmiGatewayComponent.CancelScheduledPayment(scheduledTransaction, out errorMessage);

                            // update the scheduled transaction to point to the Pi scheduled transaction
                            using (var updateRockContext = new RockContext())
                            {
                                // Attach the person to the updateRockContext so that it'll be tracked/saved using updateRockContext
                                updateRockContext.FinancialScheduledTransactions.Attach(scheduledTransaction);
                                scheduledTransaction.TransactionCode    = tempFinancialScheduledTransaction.TransactionCode;
                                scheduledTransaction.GatewayScheduleId  = tempFinancialScheduledTransaction.GatewayScheduleId;
                                scheduledTransaction.FinancialGatewayId = tempFinancialScheduledTransaction.FinancialGatewayId;
                                updateRockContext.SaveChanges();
                            }

                            scheduledTransactionResultsBuilder.AppendFormat(
                                "SUCCESS: Scheduled Transaction migration succeeded. (FinancialScheduledTransaction.Id: {0}, NMI SubscriptionId: '{1}', Pi CustomerId: {2}, Pi SubscriptionId: {3})" + Environment.NewLine,
                                scheduledTransaction.Id,
                                nmiSubscriptionId,
                                piCustomerId,
                                scheduledTransaction.GatewayScheduleId
                                );
                        }
                        else
                        {
                            scheduledTransactionResultsBuilder.AppendFormat(
                                "ERROR: Scheduled Transaction migration failed. ErrorMessage: {0}, FinancialScheduledTransaction.Id: {1}, NMI SubscriptionId: '{2}', Pi CustomerId: {3}" + Environment.NewLine,
                                errorMessage,
                                scheduledTransaction.Id,
                                nmiSubscriptionId,
                                piCustomerId
                                );
                        }
                    }
                    else
                    {
                        scheduledTransactionResultsBuilder.AppendFormat(
                            "INFO: Scheduled Transaction already migrated to PI. FinancialScheduledTransaction.Id: {0}, NMI SubscriptionId: '{1}', Pi SubscriptionId: '{2}', Pi CustomerId: {3}" + Environment.NewLine,
                            scheduledTransaction.Id,
                            nmiSubscriptionId,
                            alreadyMigratedPiSubscriptionId,
                            piCustomerId
                            );
                    }
                }
            });

            string importResult = string.Empty;

            importTask.ContinueWith((c) =>
            {
                if (c.Exception != null)
                {
                    ExceptionLogService.LogException(c.Exception);
                    scheduledTransactionResultsBuilder.AppendLine(string.Format("EXCEPTION: {0}", c.Exception.Flatten().Message));
                    importResult = "EXCEPTION";
                    UpdateProgressMessage(importResult, scheduledTransactionResultsBuilder.ToString());
                }
                else
                {
                    importResult = "Migrate Scheduled Transactions Completed Successfully";
                    UpdateProgressMessage(importResult, scheduledTransactionResultsBuilder.ToString());
                }

                this.SetBlockUserPreference("MigrateScheduledTransactionsResultSummary", importResult);
                this.SetBlockUserPreference("MigrateScheduledTransactionsResultDetails", scheduledTransactionResultsBuilder.ToString());
            });

            importTask.Start();

            nbMigrateScheduledTransactions.Visible = false;

            // wait for 5 seconds to see if this happens fast enough to do without Signal R. Otherwise, let the importTask continue and send progress to Signal R.
            var waitResult = importTask.Wait(5000);

            if (waitResult)
            {
                // wait just a little bit to make sure the importResult gets set
                System.Threading.Thread.Sleep(1000);

                nbMigrateScheduledTransactions.Visible             = true;
                nbMigrateScheduledTransactions.Title               = "Success";
                nbMigrateScheduledTransactions.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Success;

                var resultDetails = scheduledTransactionResultsBuilder.ToString();
                if (resultDetails.Contains("ERROR") || resultDetails.Contains("WARNING"))
                {
                    nbMigrateScheduledTransactions.Title = "Completed with Warnings";
                    nbMigrateScheduledTransactions.NotificationBoxType = Rock.Web.UI.Controls.NotificationBoxType.Info;
                }

                nbMigrateScheduledTransactions.Text    = importResult;
                nbMigrateScheduledTransactions.Details = resultDetails.ConvertCrLfToHtmlBr();
            }
        }
        /// <summary>
        /// Gets the name of the financial gateway.
        /// </summary>
        /// <param name="gatewayId">The gateway identifier.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        protected string GetFinancialGatewayName( int? gatewayId, RockContext rockContext )
        {
            if ( gatewayId.HasValue )
            {
                var gw = new FinancialGatewayService( rockContext ).Get( gatewayId.Value );
                if ( gw != null )
                {
                    return gw.Name;
                }
            }

            return "None";
        }
        //
        // Swipe Panel Events
        //

        private void ProcessSwipe(string swipeData)
        {
            try
            {
                using (var rockContext = new RockContext())
                {
                    // create swipe object
                    SwipePaymentInfo swipeInfo = new SwipePaymentInfo(swipeData);
                    swipeInfo.Amount = this.Amounts.Sum(a => a.Value);

                    // if not anonymous then add contact info to the gateway transaction
                    if (this.AnonymousGiverPersonAliasId != this.SelectedGivingUnit.PersonAliasId)
                    {
                        var giver = new PersonAliasService(rockContext).Queryable("Person, Person.PhoneNumbers").Where(p => p.Id == this.SelectedGivingUnit.PersonAliasId).FirstOrDefault();
                        swipeInfo.FirstName = giver.Person.NickName;
                        swipeInfo.LastName  = giver.Person.LastName;

                        if (giver.Person.PhoneNumbers != null)
                        {
                            Guid homePhoneValueGuid = new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME);
                            var  homephone          = giver.Person.PhoneNumbers.Where(p => p.NumberTypeValue.Guid == homePhoneValueGuid).FirstOrDefault();
                            if (homephone != null)
                            {
                                swipeInfo.Phone = homephone.NumberFormatted;
                            }
                        }

                        var homeLocation = giver.Person.GetHomeLocation();

                        if (homeLocation != null)
                        {
                            swipeInfo.Street1 = homeLocation.Street1;

                            if (!string.IsNullOrWhiteSpace(homeLocation.Street2))
                            {
                                swipeInfo.Street2 = homeLocation.Street2;
                            }

                            swipeInfo.City       = homeLocation.City;
                            swipeInfo.State      = homeLocation.State;
                            swipeInfo.PostalCode = homeLocation.PostalCode;
                        }
                    }

                    // add comment to the transation
                    swipeInfo.Comment1 = GetAttributeValue("PaymentComment");

                    // get gateway
                    FinancialGateway financialGateway = null;
                    GatewayComponent gateway          = null;
                    Guid?            gatewayGuid      = GetAttributeValue("CreditCardGateway").AsGuidOrNull();
                    if (gatewayGuid.HasValue)
                    {
                        financialGateway = new FinancialGatewayService(rockContext).Get(gatewayGuid.Value);
                        if (financialGateway != null)
                        {
                            financialGateway.LoadAttributes(rockContext);
                        }
                        gateway = financialGateway.GetGatewayComponent();
                    }

                    if (gateway != null)
                    {
                        string errorMessage = string.Empty;
                        var    transaction  = gateway.Charge(financialGateway, swipeInfo, out errorMessage);

                        if (transaction != null)
                        {
                            var txnChanges = new List <string>();
                            txnChanges.Add("Created Transaction (from kiosk)");

                            _transactionCode = transaction.TransactionCode;
                            History.EvaluateChange(txnChanges, "Transaction Code", string.Empty, transaction.TransactionCode);

                            var personName = new PersonAliasService(rockContext)
                                             .Queryable().AsNoTracking()
                                             .Where(a => a.Id == this.SelectedGivingUnit.PersonAliasId)
                                             .Select(a => a.Person.NickName + " " + a.Person.LastName)
                                             .FirstOrDefault();

                            transaction.AuthorizedPersonAliasId = this.SelectedGivingUnit.PersonAliasId;
                            History.EvaluateChange(txnChanges, "Person", string.Empty, personName);

                            transaction.TransactionDateTime = RockDateTime.Now;
                            History.EvaluateChange(txnChanges, "Date/Time", null, transaction.TransactionDateTime);

                            transaction.FinancialGatewayId = financialGateway.Id;
                            History.EvaluateChange(txnChanges, "Gateway", string.Empty, financialGateway.Name);

                            var txnType = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION));
                            transaction.TransactionTypeValueId = txnType.Id;
                            History.EvaluateChange(txnChanges, "Type", string.Empty, txnType.Value);

                            transaction.Summary = swipeInfo.Comment1;
                            History.EvaluateChange(txnChanges, "Transaction Code", string.Empty, transaction.Summary);

                            if (transaction.FinancialPaymentDetail == null)
                            {
                                transaction.FinancialPaymentDetail = new FinancialPaymentDetail();
                            }
                            transaction.FinancialPaymentDetail.SetFromPaymentInfo(swipeInfo, gateway, rockContext, txnChanges);

                            Guid sourceGuid = Guid.Empty;
                            if (Guid.TryParse(GetAttributeValue("Source"), out sourceGuid))
                            {
                                var source = DefinedValueCache.Read(sourceGuid);
                                if (source != null)
                                {
                                    transaction.SourceTypeValueId = source.Id;
                                    History.EvaluateChange(txnChanges, "Source", string.Empty, source.Value);
                                }
                            }

                            foreach (var accountAmount in this.Amounts.Where(a => a.Value > 0))
                            {
                                var transactionDetail = new FinancialTransactionDetail();
                                transactionDetail.Amount    = accountAmount.Value;
                                transactionDetail.AccountId = accountAmount.Key;
                                transaction.TransactionDetails.Add(transactionDetail);
                                var account = new FinancialAccountService(rockContext).Get(accountAmount.Key);
                                if (account != null)
                                {
                                    History.EvaluateChange(txnChanges, account.Name, 0.0M.FormatAsCurrency(), transactionDetail.Amount.FormatAsCurrency());
                                }
                            }

                            var batchService = new FinancialBatchService(rockContext);

                            // Get the batch
                            var batch = batchService.Get(
                                GetAttributeValue("BatchNamePrefix"),
                                swipeInfo.CurrencyTypeValue,
                                swipeInfo.CreditCardTypeValue,
                                transaction.TransactionDateTime.Value,
                                financialGateway.GetBatchTimeOffset());

                            var batchChanges = new List <string>();

                            if (batch.Id == 0)
                            {
                                batchChanges.Add("Generated the batch");
                                History.EvaluateChange(batchChanges, "Batch Name", string.Empty, batch.Name);
                                History.EvaluateChange(batchChanges, "Status", null, batch.Status);
                                History.EvaluateChange(batchChanges, "Start Date/Time", null, batch.BatchStartDateTime);
                                History.EvaluateChange(batchChanges, "End Date/Time", null, batch.BatchEndDateTime);
                            }

                            decimal newControlAmount = batch.ControlAmount + transaction.TotalAmount;
                            History.EvaluateChange(batchChanges, "Control Amount", batch.ControlAmount.FormatAsCurrency(), newControlAmount.FormatAsCurrency());
                            batch.ControlAmount = newControlAmount;

                            transaction.BatchId = batch.Id;
                            batch.Transactions.Add(transaction);

                            rockContext.WrapTransaction(() =>
                            {
                                rockContext.SaveChanges();
                                HistoryService.SaveChanges(
                                    rockContext,
                                    typeof(FinancialBatch),
                                    Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                    batch.Id,
                                    batchChanges
                                    );

                                HistoryService.SaveChanges(
                                    rockContext,
                                    typeof(FinancialBatch),
                                    Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(),
                                    batch.Id,
                                    txnChanges,
                                    personName,
                                    typeof(FinancialTransaction),
                                    transaction.Id
                                    );
                            });

                            // send receipt in one is configured and not giving anonymously
                            if (!string.IsNullOrWhiteSpace(GetAttributeValue("ReceiptEmail")) && (this.AnonymousGiverPersonAliasId != this.SelectedGivingUnit.PersonAliasId))
                            {
                                _receiptSent = true;

                                SendReceipt();
                            }

                            HidePanels();
                            ShowReceiptPanel();
                        }
                        else
                        {
                            lSwipeErrors.Text = String.Format("<div class='alert alert-danger'>An error occurred while process this transaction. Message: {0}</div>", errorMessage);
                        }
                    }
                    else
                    {
                        lSwipeErrors.Text = "<div class='alert alert-danger'>Invalid gateway provided. Please provide a gateway. Transaction not processed.</div>";
                    }
                }
            }
            catch (Exception ex)
            {
                lSwipeErrors.Text = String.Format("<div class='alert alert-danger'>An error occurred while process this transaction. Message: {0}</div>", ex.Message);
            }
        }
        /// <summary>Process all transactions (payments) from Service Reef.</summary>
        /// <param name="message">The message that is returned depending on the result.</param>
        /// <param name="state">The state of the process.</param>
        /// <returns><see cref="WorkerResultStatus"/></returns>
        public void Execute(IJobExecutionContext context)
        {
            RockContext                 dbContext                   = new RockContext();
            FinancialBatchService       financialBatchService       = new FinancialBatchService(dbContext);
            PersonService               personService               = new PersonService(dbContext);
            PersonAliasService          personAliasService          = new PersonAliasService(dbContext);
            FinancialAccountService     financialAccountService     = new FinancialAccountService(dbContext);
            FinancialAccountService     accountService              = new FinancialAccountService(dbContext);
            FinancialTransactionService financialTransactionService = new FinancialTransactionService(dbContext);
            FinancialGatewayService     financialGatewayService     = new FinancialGatewayService(dbContext);
            DefinedValueService         definedValueService         = new DefinedValueService(dbContext);
            DefinedTypeService          definedTypeService          = new DefinedTypeService(dbContext);
            TransactionService          transactionService          = new TransactionService(new PayPalReporting.Data.PayPalReportingContext());

            // Get the datamap for loading attributes
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            String warnings = string.Empty;

            FinancialBatch batch       = null;
            Double         totalAmount = 0;
            var            total       = 1;
            var            processed   = 0;

            try
            {
                DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||");

                String            SRApiKey          = Encryption.DecryptString(dataMap.GetString("ServiceReefAPIKey"));
                String            SRApiSecret       = Encryption.DecryptString(dataMap.GetString("ServiceReefAPISecret"));
                String            SRApiUrl          = dataMap.GetString("ServiceReefAPIURL");
                DefinedValueCache transactionSource = DefinedValueCache.Read(dataMap.GetString("TransactionSource").AsGuid(), dbContext);
                DefinedValueCache connectionStatus  = DefinedValueCache.Read(dataMap.GetString("ConnectionStatus").AsGuid(), dbContext);
                DefinedValueCache contribution      = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION);

                // Setup some lookups
                DefinedTypeCache        creditCards = DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE.AsGuid(), dbContext);
                DefinedTypeCache        tenderType  = DefinedTypeCache.Get(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE.AsGuid(), dbContext);
                FinancialAccount        specialFund = accountService.Get(dataMap.GetString("Account").AsGuid());
                FinancialGateway        gateway     = financialGatewayService.Get(dataMap.GetString("FinancialGateway").AsGuid());
                List <FinancialAccount> trips       = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList();

                // Get the trips
                DefinedValueCache serviceReefAccountType = DefinedValueCache.Get(dataMap.Get("ServiceReefAccountType").ToString().AsGuid());

                // Setup the ServiceReef API Client
                var client = new RestClient(SRApiUrl);
                client.Authenticator = new HMACAuthenticator(SRApiKey, SRApiSecret);

                // Get all payments from ServiceReef
                var request = new RestRequest("v1/payments", Method.GET);
                request.AddParameter("pageSize", 100);
                if (dateRange.Start.HasValue)
                {
                    request.AddParameter("startDate", dateRange.Start.Value.ToString("o"));
                }
                if (dateRange.End.HasValue)
                {
                    request.AddParameter("endDate", dateRange.End.Value.ToString("o"));
                }
                request.AddParameter("page", 1);

                while (total > processed)
                {
                    var response = client.Execute <Contracts.Payments>(request);
                    if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    {
                        throw new Exception("ServiceReef API Response: " + response.StatusDescription + " Content Length: " + response.ContentLength);
                    }
                    if (response.Data != null && response.Data.PageInfo != null)
                    {
                        total = response.Data.PageInfo.TotalRecords;
                        foreach (Contracts.Payments.Result result in response.Data.Results)
                        {
                            // Process the transaction
                            if (result.PaymentProcessorTransactionId != null)
                            {
                                if (result.FirstName == null || result.LastName == null)
                                {
                                    warnings += "Missing Firstname/Lastname for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine;
                                    processed++;
                                    continue;
                                }
                                FinancialAccount trip = null;
                                // Make sure we have a sub-account to go with this transaction
                                if (result.EventId > 0)
                                {
                                    trip = trips.Where(t => t.GlCode == result.EventCode && t.Url == result.EventUrl).FirstOrDefault();
                                }
                                if (trip == null)
                                {
                                    if (result.EventCode == null)
                                    {
                                        warnings += "Event Code is missing on the Service Reef Trip for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine;
                                        processed++;
                                        continue;
                                    }

                                    // Create the trip subaccount
                                    FinancialAccount tripFA = new FinancialAccount();
                                    tripFA.Name = result.EventName;
                                    // Name is limited to 50
                                    if (tripFA.Name.Length > 50)
                                    {
                                        tripFA.Name = tripFA.Name.Substring(0, 50);
                                    }
                                    tripFA.Description = "Service Reef Event.  Name: " + result.EventName + " ID: " + result.EventId;
                                    tripFA.GlCode      = result.EventCode;
                                    tripFA.Url         = result.EventUrl;
                                    tripFA.PublicName  = result.EventName;
                                    // Public Name is limited to 50
                                    if (tripFA.PublicName.Length > 50)
                                    {
                                        tripFA.PublicName = tripFA.PublicName.Substring(0, 50);
                                    }
                                    tripFA.IsTaxDeductible    = true;
                                    tripFA.IsPublic           = false;
                                    tripFA.ParentAccountId    = specialFund.Id;
                                    tripFA.Order              = specialFund.Order + 1;
                                    tripFA.AccountTypeValueId = serviceReefAccountType.Id;
                                    // Figure out what order it should be;
                                    foreach (FinancialAccount tmpTrip in trips)
                                    {
                                        if (tmpTrip.Name.CompareTo(tripFA.Name) < 0)
                                        {
                                            tripFA.Order++;
                                        }
                                    }

                                    financialAccountService.Add(tripFA);

                                    // Now save the trip
                                    dbContext.SaveChanges();
                                    // Increment all the rest of the Orders
                                    financialAccountService.Queryable().Where(fa => fa.Order >= tripFA.Order && fa.Id != tripFA.Id).ToList().ForEach(c => c.Order++);
                                    dbContext.SaveChanges();
                                    trips = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList();
                                    trip  = tripFA;
                                }

                                FinancialTransaction tran = financialTransactionService.Queryable().Where(tx => tx.TransactionCode == result.PaymentProcessorTransactionId).FirstOrDefault();

                                // We haven't processed this before so get busy!
                                if (tran == null)
                                {
                                    tran = new FinancialTransaction();
                                    tran.FinancialPaymentDetail = new FinancialPaymentDetail();
                                    if (result.Type == "CreditCard")
                                    {
                                        tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id;
                                    }
                                    else
                                    {
                                        tran.TransactionTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id;
                                    }

                                    Person person = null;
                                    // Find the person this transaction belongs to
                                    // 1. First start by determining whether this was a person
                                    //    paying their application fee or contributing to themselves
                                    //    because then we can just use their member info
                                    if (result.UserId > 0 &&
                                        result.DonatedToUserId == result.UserId &&
                                        result.DonatedToFirstName == result.FirstName &&
                                        result.DonatedToLastName == result.LastName)
                                    {
                                        var memberRequest = new RestRequest("v1/members/{userId}", Method.GET);
                                        memberRequest.AddUrlSegment("userId", result.UserId.ToString());
                                        var memberResult = client.Execute <Contracts.Member>(memberRequest);
                                        if (memberResult.Data != null && memberResult.Data.ArenaId > 0)
                                        {
                                            try
                                            {
                                                Person personMatch = personAliasService.Queryable().Where(pa => pa.AliasPersonId == memberResult.Data.ArenaId).Select(pa => pa.Person).FirstOrDefault();
                                                if (personMatch == null)
                                                {
                                                    throw new Exception("Person not found: " + memberResult.Data.ArenaId);
                                                }
                                                person = personMatch;
                                            } catch (Exception e)
                                            {
                                                warnings += "Loading the person failed transaction id " + result.TransactionId + " for " + result.FirstName + " " + result.LastName + " with the following error: " + e.Message + Environment.NewLine;
                                                processed++;
                                                continue;
                                            }
                                        }
                                    }
                                    // 2. If we didn't get a person match via their Alias Id
                                    //    then just use the standard person match logic
                                    if (person == null)
                                    {
                                        String street1    = null;
                                        String postalCode = null;
                                        if (result.Address != null)
                                        {
                                            street1    = result.Address.Address1;
                                            postalCode = result.Address.Zip;
                                        }
                                        List <Person> matches = personService.GetByMatch(result.FirstName.Trim(), result.LastName.Trim(), null, result.Email, null, street1, postalCode).ToList();

                                        if (matches.Count > 1)
                                        {
                                            // Find the oldest member record in the list
                                            person = matches.Where(p => p.ConnectionStatusValue.Value == "Member").OrderBy(p => p.Id).FirstOrDefault();
                                            if (person == null)
                                            {
                                                // Find the oldest attendee record in the list
                                                person = matches.Where(p => p.ConnectionStatusValue.Value == "Attendee").OrderBy(p => p.Id).FirstOrDefault();
                                                if (person == null)
                                                {
                                                    person = matches.OrderBy(p => p.Id).First();
                                                }
                                            }
                                        }
                                        else if (matches.Count == 1)
                                        {
                                            person = matches.First();
                                        }
                                        else
                                        {
                                            // Create the person
                                            person           = new Person();
                                            person.FirstName = result.FirstName.Trim();
                                            person.LastName  = result.LastName.Trim();
                                            if (result.Email.IsValidEmail())
                                            {
                                                person.Email = result.Email.Trim();
                                            }
                                            person.RecordTypeValueId       = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                                            person.ConnectionStatusValueId = connectionStatus.Id;
                                            person.RecordStatusValueId     = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id;
                                            Group         family   = PersonService.SaveNewPerson(person, dbContext);
                                            GroupLocation location = new GroupLocation();
                                            location.GroupLocationTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME).Id;
                                            location.Location = new Location()
                                            {
                                                Street1    = result.Address.Address1,
                                                Street2    = result.Address.Address2,
                                                City       = result.Address.City,
                                                State      = result.Address.State,
                                                PostalCode = result.Address.Zip,
                                                Country    = result.Address.Country
                                            };
                                            family.CampusId = CampusCache.All().FirstOrDefault().Id;
                                            family.GroupLocations.Add(location);
                                            dbContext.SaveChanges();
                                        }
                                    }

                                    // Get details about the transaction from our PayPal report table
                                    Transaction tx = transactionService.Get(result.PaymentProcessorTransactionId);
                                    if (tx != null)
                                    {
                                        if (tx.TenderType.Contains("ACH"))
                                        {
                                            result.Type   = "ACH";
                                            result.Method = null;
                                        }
                                        else
                                        {
                                            result.Type   = "Credit Card";
                                            result.Method = tx.TenderType;
                                        }
                                    }
                                    else
                                    {
                                        // Defaults
                                        result.Type   = "Credit Card";
                                        result.Method = "Visa";

                                        warnings += "Unable to find transaction in _org_secc_PaypalReporting_Transaction table: " + result.TransactionId + Environment.NewLine;
                                    }

                                    // If we don't have a batch, create one
                                    if (batch == null)
                                    {
                                        batch = new FinancialBatch();
                                        batch.BatchStartDateTime = result.Date;
                                        batch.BatchEndDateTime   = DateTime.Now;
                                        batch.Name   = "Service Reef Payments";
                                        batch.Status = BatchStatus.Open;
                                        financialBatchService.Add(batch);
                                        dbContext.SaveChanges();
                                    }

                                    // Complete the FinancialTransaction
                                    tran.AuthorizedPersonAliasId = person.PrimaryAliasId;
                                    tran.BatchId             = batch.Id;
                                    tran.Summary             = "F" + specialFund.Id + ":$" + result.Amount.ToString();
                                    tran.TransactionDateTime = result.Date;
                                    tran.FinancialGatewayId  = gateway.Id;

                                    FinancialTransactionDetail financialTransactionDetail = new FinancialTransactionDetail();
                                    financialTransactionDetail.AccountId = trip.Id;
                                    financialTransactionDetail.Amount    = result.Amount.ToString().AsDecimal();
                                    tran.TransactionDetails.Add(financialTransactionDetail);
                                    tran.TransactionTypeValueId = contribution.Id;

                                    tran.FinancialPaymentDetail = new FinancialPaymentDetail();
                                    tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(type => type.Value.ToLower() == result.Type.ToLower()).FirstOrDefault().Id;
                                    if (result.Method != null)
                                    {
                                        tran.FinancialPaymentDetail.CreditCardTypeValueId = creditCards.DefinedValues.Where(card => card.Value.ToLower() == result.Method.ToLower()).FirstOrDefault().Id;
                                    }
                                    tran.TransactionCode   = result.PaymentProcessorTransactionId;
                                    tran.SourceTypeValueId = transactionSource.Id;

                                    financialTransactionService.Add(tran);
                                    dbContext.SaveChanges();

                                    totalAmount += result.Amount;
                                }
                            }
                            processed++;
                        }
                    }
                    else
                    {
                        total = 0;
                    }
                    // Update the page number for the next request
                    var pageParam = request.Parameters.Where(p => p.Name == "page").FirstOrDefault();
                    pageParam.Value = (int)pageParam.Value + 1;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("ServiceReef Job Failed", ex);
            } finally
            {
                if (batch != null && totalAmount > 0)
                {
                    batch.ControlAmount = (Decimal)totalAmount;
                }
                dbContext.SaveChanges();
            }
            if (warnings.Length > 0)
            {
                throw new Exception(warnings);
            }
            context.Result = "Successfully imported " + processed + " transactions.";
        }