/// <summary> /// Handles the Delete event of the gSavedAccounts 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 gSavedAccounts_Delete( object sender, RowEventArgs e ) { var rockContext = new RockContext(); var service = new FinancialPersonSavedAccountService( rockContext ); var savedAccount = service.Get( e.RowKeyId ); string errorMessage; if ( savedAccount == null ) { return; } if ( !service.CanDelete( savedAccount, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } service.Delete( savedAccount ); rockContext.SaveChanges(); BindGrid(); }
/// <summary> /// Gets the reference information. /// </summary> /// <param name="savedAccountId">The saved account unique identifier.</param> /// <returns></returns> private ReferencePaymentInfo GetReferenceInfo( int savedAccountId ) { var savedAccount = new FinancialPersonSavedAccountService( new RockContext() ).Get( savedAccountId ); if ( savedAccount != null ) { return savedAccount.GetReferencePayment(); } return null; }
/// <summary> /// Binds the saved accounts. /// </summary> private void SetSavedAccounts() { rblSavedCC.Items.Clear(); if ( TargetPersonId.HasValue && TargetPersonId == CurrentPersonId ) { // Get the saved accounts for the target person var savedAccounts = new FinancialPersonSavedAccountService() .GetByPersonId( TargetPersonId.Value ); if ( Gateway != null ) { var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); rblSavedCC.DataSource = savedAccounts .Where( a => a.GatewayEntityTypeId == Gateway.TypeId && a.CurrencyTypeValueId == ccCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.MaskedAccountNumber + ")" } ).ToList(); rblSavedCC.DataBind(); if ( rblSavedCC.Items.Count > 0 ) { rblSavedCC.Items.Add( new ListItem( "Use a different card", "0" ) ); } var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); rblSavedAch.DataSource = savedAccounts .Where( a => a.GatewayEntityTypeId == Gateway.TypeId && a.CurrencyTypeValueId == achCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.MaskedAccountNumber + ")" } ).ToList(); rblSavedAch.DataBind(); if ( rblSavedAch.Items.Count > 0 ) { rblSavedAch.Items.Add( new ListItem( "Use a different bank account", "0" ) ); } } } 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"; } }
/// <summary> /// Gets the reference information. /// </summary> /// <param name="savedAccountId">The saved account unique identifier.</param> /// <returns></returns> private ReferencePaymentInfo GetReferenceInfo( int savedAccountId ) { using ( new UnitOfWorkScope() ) { var savedAccount = new FinancialPersonSavedAccountService().Get( savedAccountId ); if ( savedAccount != null ) { var reference = new ReferencePaymentInfo(); reference.TransactionCode = savedAccount.TransactionCode; reference.ReferenceNumber = savedAccount.ReferenceNumber; reference.MaskedAccountNumber = savedAccount.MaskedAccountNumber; reference.InitialCurrencyTypeValue = DefinedValueCache.Read( savedAccount.CurrencyTypeValue ); if ( reference.InitialCurrencyTypeValue.Guid.Equals( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ) ) { reference.InitialCreditCardTypeValue = DefinedValueCache.Read( savedAccount.CreditCardTypeValue ); } return reference; } } return null; }
/// <summary> /// Binds the saved accounts. /// </summary> private void BindSavedAccounts() { rblSavedCC.Items.Clear(); if ( TargetPerson != null ) { // Get the saved accounts for the currently logged in user var savedAccounts = new FinancialPersonSavedAccountService( new RockContext() ) .GetByPersonId( TargetPerson.Id ); if ( _ccGateway != null ) { var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); rblSavedCC.DataSource = savedAccounts .Where( a => a.GatewayEntityTypeId == _ccGateway.TypeId && a.CurrencyTypeValueId == ccCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.MaskedAccountNumber + ")" } ).ToList(); rblSavedCC.DataBind(); if ( rblSavedCC.Items.Count > 0 ) { rblSavedCC.Items.Add( new ListItem( "Use a different card", "0" ) ); } } if ( _achGateway != null ) { var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); rblSavedAch.DataSource = savedAccounts .Where( a => a.GatewayEntityTypeId == _achGateway.TypeId && a.CurrencyTypeValueId == achCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.MaskedAccountNumber + ")" } ).ToList(); rblSavedAch.DataBind(); if ( rblSavedAch.Items.Count > 0 ) { rblSavedAch.Items.Add( new ListItem( "Use a different bank account", "0" ) ); } } } }
/// <summary> /// Handles the Click event of the lbSaveAccount 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 lbSaveAccount_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); if ( string.IsNullOrWhiteSpace( TransactionCode ) ) { nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference"; nbSaveAccount.Visible = true; return; } if ( phCreateLogin.Visible ) { if ( string.IsNullOrWhiteSpace( txtUserName.Text ) || string.IsNullOrWhiteSpace( txtPassword.Text ) ) { nbSaveAccount.Title = "Missing Informaton"; nbSaveAccount.Text = "A username and password are required when saving an account"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( new UserLoginService( rockContext ).GetByUserName( txtUserName.Text ) != null ) { nbSaveAccount.Title = "Invalid Username"; nbSaveAccount.Text = "The selected Username is already being used. Please select a different Username"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( txtPasswordConfirm.Text != txtPassword.Text ) { nbSaveAccount.Title = "Invalid Password"; nbSaveAccount.Text = "The password and password confirmation do not match"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } } if ( !string.IsNullOrWhiteSpace( txtSaveAccount.Text ) ) { GatewayComponent gateway = hfPaymentTab.Value == "ACH" ? _achGateway : _ccGateway; var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); string errorMessage = string.Empty; PersonAlias authorizedPersonAlias = null; string referenceNumber = string.Empty; int? currencyTypeValueId = hfPaymentTab.Value == "ACH" ? achCurrencyType.Id : ccCurrencyType.Id; if ( string.IsNullOrWhiteSpace( ScheduleId ) ) { var transaction = new FinancialTransactionService( rockContext ).GetByTransactionCode( TransactionCode ); if ( transaction != null && transaction.AuthorizedPersonAlias != null ) { authorizedPersonAlias = transaction.AuthorizedPersonAlias; referenceNumber = gateway.GetReferenceNumber( transaction, out errorMessage ); } } else { var scheduledTransaction = new FinancialScheduledTransactionService( rockContext ).GetByScheduleId( ScheduleId ); if ( scheduledTransaction != null ) { authorizedPersonAlias = scheduledTransaction.AuthorizedPersonAlias; referenceNumber = gateway.GetReferenceNumber( scheduledTransaction, out errorMessage ); } } if ( authorizedPersonAlias != null && authorizedPersonAlias.Person != null ) { if ( phCreateLogin.Visible ) { var user = UserLoginService.Create( rockContext, authorizedPersonAlias.Person, Rock.Model.AuthenticationServiceType.Internal, EntityTypeCache.Read( Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid() ).Id, txtUserName.Text, txtPassword.Text, false ); var mergeObjects = GlobalAttributesCache.GetMergeFields( null ); mergeObjects.Add( "ConfirmAccountUrl", RootPath + "ConfirmAccount" ); var personDictionary = authorizedPersonAlias.Person.ToLiquid() as Dictionary<string, object>; mergeObjects.Add( "Person", personDictionary ); mergeObjects.Add( "User", user ); var recipients = new List<Rock.Communication.RecipientData>(); recipients.Add( new Rock.Communication.RecipientData( authorizedPersonAlias.Person.Email, mergeObjects ) ); Rock.Communication.Email.Send( GetAttributeValue( "ConfirmAccountTemplate" ).AsGuid(), recipients, ResolveRockUrl( "~/" ), ResolveRockUrl( "~~/" ) ); } var paymentInfo = GetPaymentInfo(); if ( errorMessage.Any() ) { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved. " + errorMessage; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } else { if ( authorizedPersonAlias != null ) { var savedAccount = new FinancialPersonSavedAccount(); savedAccount.PersonAliasId = authorizedPersonAlias.Id; savedAccount.ReferenceNumber = referenceNumber; savedAccount.Name = txtSaveAccount.Text; savedAccount.MaskedAccountNumber = paymentInfo.MaskedNumber; savedAccount.TransactionCode = TransactionCode; savedAccount.GatewayEntityTypeId = gateway.TypeId; savedAccount.CurrencyTypeValueId = currencyTypeValueId; savedAccount.CreditCardTypeValueId = CreditCardTypeValueId; var savedAccountService = new FinancialPersonSavedAccountService( rockContext ); savedAccountService.Add( savedAccount ); rockContext.SaveChanges(); cbSaveAccount.Visible = false; txtSaveAccount.Visible = false; phCreateLogin.Visible = false; divSaveActions.Visible = false; nbSaveAccount.Title = "Success"; nbSaveAccount.Text = "The account has been saved for future use"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Success; nbSaveAccount.Visible = true; } } } else { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Missing Account Name"; nbSaveAccount.Text = "Please enter a name to use for this account"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } }
/// <summary> /// This method is called in the /// <see cref="M:Rock.Data.Model`1.PreSaveChanges(Rock.Data.DbContext,System.Data.Entity.Infrastructure.DbEntityEntry,System.Data.Entity.EntityState)" /> /// method. Use it to populate <see cref="P:Rock.Data.Model`1.HistoryItems" /> if needed. /// These history items are queued to be written into the database post save (so that they /// are only written if the save actually occurs). /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry">The entry.</param> /// <param name="state">The state.</param> protected override void BuildHistoryItems(Data.DbContext dbContext, DbEntityEntry entry, EntityState state) { // Sometimes, especially if the model is being deleted, some properties might not be // populated, but we can query to try to get their original value. We need to use a new // rock context to get the actual value from the DB var rockContext = new RockContext(); var service = new FinancialPersonSavedAccountService(rockContext); var originalModel = service.Queryable("PersonAlias, FinancialPaymentDetail") .FirstOrDefault(fpsa => fpsa.Id == Id); // Use the original value for the person alias or the new value if that is not set var personId = (originalModel?.PersonAlias ?? PersonAlias)?.PersonId; if (!personId.HasValue) { // If this model is new, it won't have any virtual properties hydrated or an original // record in the database if (PersonAliasId.HasValue) { var personAliasService = new PersonAliasService(rockContext); var personAlias = personAliasService.Get(PersonAliasId.Value); personId = personAlias?.PersonId; } // We can't log history if we don't know who the saved account belongs to if (!personId.HasValue) { return; } } History.HistoryVerb verb; switch (state) { case EntityState.Added: verb = History.HistoryVerb.Add; break; case EntityState.Deleted: verb = History.HistoryVerb.Delete; break; default: // As of now, there is no requirement to log other events return; } var historyChangeList = new History.HistoryChangeList(); historyChangeList.AddChange(verb, History.HistoryChangeType.Record, "Financial Person Saved Account"); HistoryItems = HistoryService.GetChanges( typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON.AsGuid(), personId.Value, historyChangeList, GetNameForHistory(originalModel?.FinancialPaymentDetail ?? FinancialPaymentDetail), typeof(FinancialPersonSavedAccount), Id, dbContext.GetCurrentPersonAlias()?.Id, dbContext.SourceOfChange); }
/// <summary> /// Processes the payment. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="registration">The registration.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ProcessPayment( RockContext rockContext, Registration registration, out string errorMessage ) { GatewayComponent gateway = null; if ( RegistrationTemplate != null && RegistrationTemplate.FinancialGateway != null ) { gateway = RegistrationTemplate.FinancialGateway.GetGatewayComponent(); } if ( gateway == null ) { errorMessage = "There was a problem creating the payment gateway information"; return false; } if ( !RegistrationInstanceState.AccountId.HasValue || RegistrationInstanceState.Account == null ) { errorMessage = "There was a problem with the account configuration for this " + RegistrationTerm.ToLower(); return false; } PaymentInfo paymentInfo = null; if ( rblSavedCC.Items.Count > 0 && ( rblSavedCC.SelectedValueAsId() ?? 0 ) > 0 ) { var savedAccount = new FinancialPersonSavedAccountService( new RockContext() ).Get( rblSavedCC.SelectedValueAsId().Value ); if ( savedAccount != null ) { paymentInfo = savedAccount.GetReferencePayment(); paymentInfo.Amount = RegistrationState.PaymentAmount ?? 0.0m; } else { errorMessage = "There was a problem retrieving the saved account"; return false; } } else { paymentInfo = GetCCPaymentInfo( gateway ); } paymentInfo.Comment1 = string.Format( "{0} ({1})", RegistrationInstanceState.Name, RegistrationInstanceState.Account.GlCode ); var transaction = gateway.Charge( RegistrationTemplate.FinancialGateway, paymentInfo, out errorMessage ); if ( transaction != null ) { var txnChanges = new List<string>(); txnChanges.Add( "Created Transaction" ); History.EvaluateChange( txnChanges, "Transaction Code", string.Empty, transaction.TransactionCode ); transaction.AuthorizedPersonAliasId = registration.PersonAliasId; transaction.TransactionDateTime = RockDateTime.Now; History.EvaluateChange( txnChanges, "Date/Time", null, transaction.TransactionDateTime ); transaction.FinancialGatewayId = RegistrationTemplate.FinancialGatewayId; History.EvaluateChange( txnChanges, "Gateway", string.Empty, RegistrationTemplate.FinancialGateway.Name ); var txnType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_EVENT_REGISTRATION ) ); transaction.TransactionTypeValueId = txnType.Id; History.EvaluateChange( txnChanges, "Type", string.Empty, txnType.Value ); if ( transaction.FinancialPaymentDetail == null ) { transaction.FinancialPaymentDetail = new FinancialPaymentDetail(); } transaction.FinancialPaymentDetail.SetFromPaymentInfo( paymentInfo, 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 ); } } transaction.Summary = registration.GetSummary( RegistrationInstanceState ); var transactionDetail = new FinancialTransactionDetail(); transactionDetail.Amount = RegistrationState.PaymentAmount ?? 0.0m; transactionDetail.AccountId = RegistrationInstanceState.AccountId.Value; transactionDetail.EntityTypeId = EntityTypeCache.Read( typeof( Rock.Model.Registration ) ).Id; transactionDetail.EntityId = registration.Id; transaction.TransactionDetails.Add( transactionDetail ); History.EvaluateChange( txnChanges, RegistrationInstanceState.Account.Name, 0.0M.FormatAsCurrency(), transactionDetail.Amount.FormatAsCurrency() ); var batchChanges = new List<string>(); rockContext.WrapTransaction( () => { var batchService = new FinancialBatchService( rockContext ); // Get the batch var batch = batchService.Get( GetAttributeValue( "BatchNamePrefix" ), paymentInfo.CurrencyTypeValue, paymentInfo.CreditCardTypeValue, transaction.TransactionDateTime.Value, RegistrationTemplate.FinancialGateway.GetBatchTimeOffset() ); 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.SaveChanges(); } ); if ( transaction.BatchId.HasValue ) { Task.Run( () => HistoryService.SaveChanges( new RockContext(), typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(), transaction.BatchId.Value, batchChanges, true, CurrentPersonAliasId ) ); Task.Run( () => HistoryService.SaveChanges( new RockContext(), typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), transaction.BatchId.Value, txnChanges, CurrentPerson != null ? CurrentPerson.FullName : string.Empty, typeof( FinancialTransaction ), transaction.Id, true, CurrentPersonAliasId ) ); } List<string> registrationChanges = new List<string>(); registrationChanges.Add( string.Format( "Made {0} payment", transaction.TotalAmount.FormatAsCurrency() ) ); Task.Run( () => HistoryService.SaveChanges( new RockContext(), typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), registration.Id, registrationChanges, true, CurrentPersonAliasId ) ); TransactionCode = transaction.TransactionCode; return true; } else { return false; } }
/// <summary> /// Processes the first step of a 3-step charge. /// </summary> /// <param name="registration">The registration.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ProcessStep1( out string errorMessage ) { ThreeStepGatewayComponent gateway = null; if ( RegistrationTemplate != null && RegistrationTemplate.FinancialGateway != null ) { gateway = RegistrationTemplate.FinancialGateway.GetGatewayComponent() as ThreeStepGatewayComponent; } if ( gateway == null ) { errorMessage = "There was a problem creating the payment gateway information"; return false; } if ( !RegistrationInstanceState.AccountId.HasValue || RegistrationInstanceState.Account == null ) { errorMessage = "There was a problem with the account configuration for this " + RegistrationTerm.ToLower(); return false; } PaymentInfo paymentInfo = null; if ( rblSavedCC.Items.Count > 0 && ( rblSavedCC.SelectedValueAsId() ?? 0 ) > 0 ) { var rockContext = new RockContext(); var savedAccount = new FinancialPersonSavedAccountService( rockContext ).Get( rblSavedCC.SelectedValueAsId().Value ); if ( savedAccount != null ) { paymentInfo = savedAccount.GetReferencePayment(); paymentInfo.Amount = RegistrationState.PaymentAmount ?? 0.0m; } else { errorMessage = "There was a problem retrieving the saved account"; return false; } } else { paymentInfo = new PaymentInfo(); paymentInfo.Amount = RegistrationState.PaymentAmount ?? 0.0m; paymentInfo.Email = RegistrationState.ConfirmationEmail; paymentInfo.FirstName = RegistrationState.FirstName; paymentInfo.LastName = RegistrationState.LastName; } paymentInfo.Description = string.Format( "{0} ({1})", RegistrationInstanceState.Name, RegistrationInstanceState.Account.GlCode ); paymentInfo.IPAddress = GetClientIpAddress(); paymentInfo.AdditionalParameters = gateway.GetStep1Parameters( ResolveRockUrlIncludeRoot( "~/GatewayStep2Return.aspx" ) ); var result = gateway.ChargeStep1( RegistrationTemplate.FinancialGateway, paymentInfo, out errorMessage ); if ( string.IsNullOrWhiteSpace( errorMessage ) && !string.IsNullOrWhiteSpace( result ) ) { hfStep2Url.Value = result; } return string.IsNullOrWhiteSpace( errorMessage ); }
/// <summary> /// Processes the payment. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="registration">The registration.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ProcessPayment( RockContext rockContext, Registration registration, out string errorMessage ) { GatewayComponent gateway = null; if ( RegistrationTemplate != null && RegistrationTemplate.FinancialGateway != null ) { gateway = RegistrationTemplate.FinancialGateway.GetGatewayComponent(); } if ( gateway == null ) { errorMessage = "There was a problem creating the payment gateway information"; return false; } if ( !RegistrationInstanceState.AccountId.HasValue || RegistrationInstanceState.Account == null ) { errorMessage = "There was a problem with the account configuration for this " + RegistrationTerm.ToLower(); return false; } PaymentInfo paymentInfo = null; if ( rblSavedCC.Items.Count > 0 && ( rblSavedCC.SelectedValueAsId() ?? 0 ) > 0 ) { var savedAccount = new FinancialPersonSavedAccountService( rockContext ).Get( rblSavedCC.SelectedValueAsId().Value ); if ( savedAccount != null ) { paymentInfo = savedAccount.GetReferencePayment(); paymentInfo.Amount = RegistrationState.PaymentAmount ?? 0.0m; } else { errorMessage = "There was a problem retrieving the saved account"; return false; } } else { paymentInfo = GetCCPaymentInfo( gateway ); } paymentInfo.Comment1 = string.Format( "{0} ({1})", RegistrationInstanceState.Name, RegistrationInstanceState.Account.GlCode ); var transaction = gateway.Charge( RegistrationTemplate.FinancialGateway, paymentInfo, out errorMessage ); return SaveTransaction( gateway, registration, transaction, paymentInfo, rockContext ); }
private void BindSavedAccounts( GatewayComponent component ) { var currentValue = rblSavedCC.SelectedValue; rblSavedCC.Items.Clear(); if ( CurrentPerson != null ) { // Get the saved accounts for the currently logged in user var savedAccounts = new FinancialPersonSavedAccountService( new RockContext() ) .GetByPersonId( CurrentPerson.Id ); // Verify component is valid and that it supports using saved accounts for one-time, credit card transactions var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); if ( component != null && component.SupportsSavedAccount( false ) && component.SupportsSavedAccount( ccCurrencyType ) ) { rblSavedCC.DataSource = savedAccounts .Where( a => a.FinancialGatewayId == RegistrationTemplate.FinancialGateway.Id && a.FinancialPaymentDetail != null && a.FinancialPaymentDetail.CurrencyTypeValueId == ccCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.FinancialPaymentDetail.AccountNumberMasked + ")" } ).ToList(); rblSavedCC.DataBind(); if ( rblSavedCC.Items.Count > 0 ) { rblSavedCC.Items.Add( new ListItem( "Use a different card", "0" ) ); rblSavedCC.SetValue( currentValue ); } } } }
/// <summary> /// Removes the expired saved accounts. /// </summary> /// <param name="removedExpiredSavedAccountDays">The removed expired saved account days.</param> /// <returns></returns> internal RemoveExpiredSavedAccountsResult RemoveExpiredSavedAccounts(int removedExpiredSavedAccountDays) { var financialPersonSavedAccountQry = new FinancialPersonSavedAccountService(new RockContext()).Queryable() .Where(a => a.FinancialPaymentDetail.CardExpirationDate != null && (a.PersonAliasId.HasValue || a.GroupId.HasValue) && a.FinancialPaymentDetailId.HasValue && a.IsSystem == false) .OrderBy(a => a.Id); var savedAccountInfoList = financialPersonSavedAccountQry.Select(a => new { Id = a.Id, FinancialPaymentDetail = a.FinancialPaymentDetail }).ToList(); DateTime now = RockDateTime.Now; int currentMonth = now.Month; int currentYear = now.Year; var result = new RemoveExpiredSavedAccountsResult() { // if today is 3/16/2020 and removedExpiredSavedAccountDays is 90, only delete card if it expired before 12/17/2019 DeleteIfExpiredBeforeDate = RockDateTime.Today.AddDays(-removedExpiredSavedAccountDays) }; foreach (var savedAccountInfo in savedAccountInfoList) { int?expirationMonth = savedAccountInfo.FinancialPaymentDetail.ExpirationMonth; int?expirationYear = savedAccountInfo.FinancialPaymentDetail.ExpirationYear; if (!expirationMonth.HasValue || !expirationYear.HasValue) { continue; } if (expirationMonth.Value < 1 || expirationMonth.Value > 12 || expirationYear <= DateTime.MinValue.Year || expirationYear >= DateTime.MaxValue.Year) { // invalid month (or year) continue; } // a credit card with an expiration of April 2020 would be expired on May 1st, 2020 var cardExpirationDate = new DateTime(expirationYear.Value, expirationMonth.Value, 1).AddMonths(1); /* Example: * Today's Date: 2020-3-16 * removedExpiredSavedAccountDays: 90 * Expired Before Date: 2019-12-17 (Today (2020-3-16) - removedExpiredSavedAccountDays) * Cards that expired before 2019-12-17 should be deleted * Delete 04/20 (Expires 05/01/2020) card? No * Delete 05/20 (Expires 06/01/2020) card? No * Delete 01/20 (Expires 03/01/2020) card? No * Delete 12/19 (Expires 01/01/2020) card? No * Delete 11/19 (Expires 12/01/2019) card? Yes * Delete 10/19 (Expires 11/01/2019) card? Yes * * Today's Date: 2020-3-16 * removedExpiredSavedAccountDays: 0 * Expired Before Date: 2019-03-16 (Today (2020-3-16) - 0) * Cards that expired before 2019-03-16 should be deleted * Delete 04/20 (Expires 05/01/2020) card? No * Delete 05/20 (Expires 06/01/2020) card? No * Delete 01/20 (Expires 03/01/2020) card? Yes * Delete 12/19 (Expires 01/01/2020) card? Yes * Delete 11/19 (Expires 12/01/2019) card? Yes * Delete 10/19 (Expires 11/01/2019) card? Yes */ if (cardExpirationDate >= result.DeleteIfExpiredBeforeDate) { // We want to only delete cards that expired more than X days ago, so if this card expiration day is after that, skip continue; } // Card expiration date is older than X day ago, so delete it. // Wrapping the following in a try/catch so a single deletion failure doesn't end the process for all deletion candidates. try { using (var savedAccountRockContext = new RockContext()) { var financialPersonSavedAccountService = new FinancialPersonSavedAccountService(savedAccountRockContext); var financialPersonSavedAccount = financialPersonSavedAccountService.Get(savedAccountInfo.Id); if (financialPersonSavedAccount != null) { if (financialPersonSavedAccountService.CanDelete(financialPersonSavedAccount, out _)) { financialPersonSavedAccountService.Delete(financialPersonSavedAccount); savedAccountRockContext.SaveChanges(); result.AccountsDeletedCount++; } } } } catch (Exception ex) { // Provide better identifying context in case the caught exception is too vague. var exception = new Exception($"Unable to delete FinancialPersonSavedAccount (ID = {savedAccountInfo.Id}).", ex); result.AccountRemovalExceptions.Add(exception); } } return(result); }
/// <summary> /// Binds the saved accounts. /// </summary> private void BindSavedAccounts() { rblSavedCC.Items.Clear(); if ( TargetPerson != null ) { // Get the saved accounts for the currently logged in user var savedAccounts = new FinancialPersonSavedAccountService( new RockContext() ) .GetByPersonId( TargetPerson.Id ); if ( _ccGateway != null ) { var ccGatewayComponent = _ccGateway.GetGatewayComponent(); var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); if ( ccGatewayComponent != null && ccGatewayComponent.SupportsSavedAccount( ccCurrencyType ) ) { rblSavedCC.DataSource = savedAccounts .Where( a => a.FinancialGatewayId == _ccGateway.Id && a.FinancialPaymentDetail != null && a.FinancialPaymentDetail.CurrencyTypeValueId == ccCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.FinancialPaymentDetail.AccountNumberMasked + ")" } ).ToList(); rblSavedCC.DataBind(); if ( rblSavedCC.Items.Count > 0 ) { rblSavedCC.Items.Add( new ListItem( "Use a different card", "0" ) ); CollapseCardData.Value = "true"; } } } if ( _achGateway != null ) { var achGatewayComponent = _ccGateway.GetGatewayComponent(); var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); if ( achGatewayComponent != null && achGatewayComponent.SupportsSavedAccount( achCurrencyType ) ) { rblSavedAch.DataSource = savedAccounts .Where( a => a.FinancialGatewayId == _achGateway.Id && a.FinancialPaymentDetail != null && a.FinancialPaymentDetail.CurrencyTypeValueId == achCurrencyType.Id ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.FinancialPaymentDetail.AccountNumberMasked + ")" } ).ToList(); rblSavedAch.DataBind(); } divRecentCheck.Style[HtmlTextWriterStyle.Display] = "none"; var aliasIds = TargetPerson.Aliases.Select( y => y.Id ).ToList(); var prevChecks = new FinancialTransactionService( new RockContext() ).Queryable().Where( x => aliasIds.Contains( x.AuthorizedPersonAliasId ?? -1 ) ).Where( x => x.CheckMicrParts != null ).SortBy( "CreatedDateTime Desc" ).Take( 3 ).ToList().Select( x => (Rock.Security.Encryption.DecryptString( x.CheckMicrParts ) ?? "").Split( '_' ) ).Select( x => x.ElementAtOrDefault( 0 ) + "_" + x.ElementAtOrDefault( 1 ) ); if ( prevChecks.Distinct().Count() == 1 && prevChecks.FirstOrDefault() != "_" ) { rblSavedAch.Items.Add( new ListItem( "Use recent check", "-1" ) ); var achDat = prevChecks.FirstOrDefault().Split( '_' ); if ( achDat.Count() == 2 ) { if ( !IsPostBack ) { txtCheckRoutingNumber.Text = achDat[0]; txtCheckAccountNumber.Text = achDat[1]; } } if ( PageParameter( "flc" ) == "1" && !IsPostBack ) { hfPaymentTab.Value = "ACH"; rblSavedAch.SelectedValue = "-1"; } } if ( rblSavedAch.Items.Count > 0 ) { rblSavedAch.Items.Add( new ListItem( "Use a different bank account", "0" ) ); CollapseCardData.Value = "true"; } } if ( rblSavedCC.Items.Count <= 0 && rblSavedAch.Items.Count > 0 ) { hfPaymentTab.Value = "ACH"; } } }
/// <summary> /// Handles the Click event of the lbSaveAccount 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 lbSaveAccount_Click( object sender, EventArgs e ) { if ( string.IsNullOrWhiteSpace( TransactionCode ) ) { nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference"; nbSaveAccount.Visible = true; return; } using ( var rockContext = new RockContext() ) { if ( phCreateLogin.Visible ) { if ( string.IsNullOrWhiteSpace( txtUserName.Text ) || string.IsNullOrWhiteSpace( txtPassword.Text ) ) { nbSaveAccount.Title = "Missing Informaton"; nbSaveAccount.Text = "A username and password are required when saving an account"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( new UserLoginService( rockContext ).GetByUserName( txtUserName.Text ) != null ) { nbSaveAccount.Title = "Invalid Username"; nbSaveAccount.Text = "The selected Username is already being used. Please select a different Username"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( !UserLoginService.IsPasswordValid( txtPassword.Text ) ) { nbSaveAccount.Title = string.Empty; nbSaveAccount.Text = UserLoginService.FriendlyPasswordRules(); nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( txtPasswordConfirm.Text != txtPassword.Text ) { nbSaveAccount.Title = "Invalid Password"; nbSaveAccount.Text = "The password and password confirmation do not match"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } } if ( !string.IsNullOrWhiteSpace( txtSaveAccount.Text ) ) { GatewayComponent gateway = null; if ( RegistrationTemplate != null && RegistrationTemplate.FinancialGateway != null ) { gateway = RegistrationTemplate.FinancialGateway.GetGatewayComponent(); } if ( gateway != null ) { var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); string errorMessage = string.Empty; PersonAlias authorizedPersonAlias = null; string referenceNumber = string.Empty; int? currencyTypeValueId = ccCurrencyType.Id; var transaction = new FinancialTransactionService( rockContext ).GetByTransactionCode( TransactionCode ); if ( transaction != null && transaction.AuthorizedPersonAlias != null ) { authorizedPersonAlias = transaction.AuthorizedPersonAlias; if ( transaction.FinancialGateway != null ) { transaction.FinancialGateway.LoadAttributes( rockContext ); } referenceNumber = gateway.GetReferenceNumber( transaction, out errorMessage ); } if ( authorizedPersonAlias != null && authorizedPersonAlias.Person != null ) { if ( phCreateLogin.Visible ) { var user = UserLoginService.Create( rockContext, authorizedPersonAlias.Person, Rock.Model.AuthenticationServiceType.Internal, EntityTypeCache.Read( Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid() ).Id, txtUserName.Text, txtPassword.Text, false ); var mergeObjects = Rock.Lava.LavaHelper.GetCommonMergeFields(RockPage); mergeObjects.Add( "ConfirmAccountUrl", RootPath + "ConfirmAccount" ); var personDictionary = authorizedPersonAlias.Person.ToLiquid() as Dictionary<string, object>; mergeObjects.Add( "Person", personDictionary ); mergeObjects.Add( "User", user ); var recipients = new List<Rock.Communication.RecipientData>(); recipients.Add( new Rock.Communication.RecipientData( authorizedPersonAlias.Person.Email, mergeObjects ) ); try { Rock.Communication.Email.Send( GetAttributeValue( "ConfirmAccountTemplate" ).AsGuid(), recipients, ResolveRockUrl( "~/" ), ResolveRockUrl( "~~/" ), false ); } catch (Exception ex) { ExceptionLogService.LogException( ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias ); } } var paymentInfo = GetCCPaymentInfo( gateway ); if ( errorMessage.Any() ) { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved. " + errorMessage; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } else { if ( authorizedPersonAlias != null ) { var savedAccount = new FinancialPersonSavedAccount(); savedAccount.PersonAliasId = authorizedPersonAlias.Id; savedAccount.ReferenceNumber = referenceNumber; savedAccount.Name = txtSaveAccount.Text; savedAccount.TransactionCode = TransactionCode; savedAccount.FinancialGatewayId = RegistrationTemplate.FinancialGateway.Id; savedAccount.FinancialPaymentDetail = new FinancialPaymentDetail(); savedAccount.FinancialPaymentDetail.SetFromPaymentInfo( paymentInfo, gateway, rockContext ); var savedAccountService = new FinancialPersonSavedAccountService( rockContext ); savedAccountService.Add( savedAccount ); rockContext.SaveChanges(); cbSaveAccount.Visible = false; txtSaveAccount.Visible = false; phCreateLogin.Visible = false; divSaveActions.Visible = false; nbSaveAccount.Title = "Success"; nbSaveAccount.Text = "The account has been saved for future use"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Success; nbSaveAccount.Visible = true; } } } else { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Invalid Gateway"; nbSaveAccount.Text = "Sorry, the financial gateway information for this type of transaction is not valid."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Missing Account Name"; nbSaveAccount.Text = "Please enter a name to use for this account."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } }
/// <summary> /// Handles the Click event of the lbSaveAccount 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 lbSaveAccount_Click( object sender, EventArgs e ) { if ( string.IsNullOrWhiteSpace( TransactionCode ) ) { nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference"; nbSaveAccount.Visible = true; return; } using ( var rockContext = new RockContext() ) { if ( phCreateLogin.Visible ) { if ( string.IsNullOrWhiteSpace( txtUserName.Text ) || string.IsNullOrWhiteSpace( txtPassword.Text ) ) { nbSaveAccount.Title = "Missing Informaton"; nbSaveAccount.Text = "A username and password are required when saving an account"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( new UserLoginService( rockContext ).GetByUserName( txtUserName.Text ) != null ) { nbSaveAccount.Title = "Invalid Username"; nbSaveAccount.Text = "The selected Username is already being used. Please select a different Username"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( !UserLoginService.IsPasswordValid( txtPassword.Text ) ) { nbSaveAccount.Title = string.Empty; nbSaveAccount.Text = UserLoginService.FriendlyPasswordRules(); nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } if ( txtPasswordConfirm.Text != txtPassword.Text ) { nbSaveAccount.Title = "Invalid Password"; nbSaveAccount.Text = "The password and password confirmation do not match"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; return; } } if ( !string.IsNullOrWhiteSpace( txtSaveAccount.Text ) ) { bool isACHTxn = hfPaymentTab.Value == "ACH"; var financialGateway = isACHTxn ? _achGateway : _ccGateway; var gateway = isACHTxn ? _achGatewayComponent : _ccGatewayComponent; if ( gateway != null ) { var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); string errorMessage = string.Empty; var person = GetPerson( false ); string referenceNumber = string.Empty; FinancialPaymentDetail paymentDetail = null; int? currencyTypeValueId = isACHTxn ? achCurrencyType.Id : ccCurrencyType.Id; if ( string.IsNullOrWhiteSpace( ScheduleId ) ) { var transaction = new FinancialTransactionService( rockContext ).GetByTransactionCode( TransactionCode ); if ( transaction != null && transaction.AuthorizedPersonAlias != null ) { if ( transaction.FinancialGateway != null ) { transaction.FinancialGateway.LoadAttributes( rockContext ); } referenceNumber = gateway.GetReferenceNumber( transaction, out errorMessage ); paymentDetail = transaction.FinancialPaymentDetail; } } else { var scheduledTransaction = new FinancialScheduledTransactionService( rockContext ).GetByScheduleId( ScheduleId ); if ( scheduledTransaction != null ) { if ( scheduledTransaction.FinancialGateway != null ) { scheduledTransaction.FinancialGateway.LoadAttributes( rockContext ); } referenceNumber = gateway.GetReferenceNumber( scheduledTransaction, out errorMessage ); paymentDetail = scheduledTransaction.FinancialPaymentDetail; } } if ( person != null && paymentDetail != null ) { if ( phCreateLogin.Visible ) { var user = UserLoginService.Create( rockContext, person, Rock.Model.AuthenticationServiceType.Internal, EntityTypeCache.Read( Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid() ).Id, txtUserName.Text, txtPassword.Text, false ); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); mergeFields.Add( "ConfirmAccountUrl", RootPath + "ConfirmAccount" ); var personDictionary = person.ToLiquid() as Dictionary<string, object>; mergeFields.Add( "Person", personDictionary ); mergeFields.Add( "User", user ); var recipients = new List<Rock.Communication.RecipientData>(); recipients.Add( new Rock.Communication.RecipientData( person.Email, mergeFields ) ); Rock.Communication.Email.Send( GetAttributeValue( "ConfirmAccountTemplate" ).AsGuid(), recipients, ResolveRockUrl( "~/" ), ResolveRockUrl( "~~/" ), false ); } if ( errorMessage.Any() ) { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved. " + errorMessage; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } else { var savedAccount = new FinancialPersonSavedAccount(); savedAccount.PersonAliasId = person.PrimaryAliasId; savedAccount.ReferenceNumber = referenceNumber; savedAccount.Name = txtSaveAccount.Text; savedAccount.TransactionCode = TransactionCode; savedAccount.FinancialGatewayId = financialGateway.Id; savedAccount.FinancialPaymentDetail = new FinancialPaymentDetail(); savedAccount.FinancialPaymentDetail.AccountNumberMasked = paymentDetail.AccountNumberMasked; savedAccount.FinancialPaymentDetail.CurrencyTypeValueId = paymentDetail.CurrencyTypeValueId; savedAccount.FinancialPaymentDetail.CreditCardTypeValueId = paymentDetail.CreditCardTypeValueId; savedAccount.FinancialPaymentDetail.NameOnCardEncrypted = paymentDetail.NameOnCardEncrypted; savedAccount.FinancialPaymentDetail.ExpirationMonthEncrypted = paymentDetail.ExpirationMonthEncrypted; savedAccount.FinancialPaymentDetail.ExpirationYearEncrypted = paymentDetail.ExpirationYearEncrypted; savedAccount.FinancialPaymentDetail.BillingLocationId = paymentDetail.BillingLocationId; var savedAccountService = new FinancialPersonSavedAccountService( rockContext ); savedAccountService.Add( savedAccount ); rockContext.SaveChanges(); cbSaveAccount.Visible = false; txtSaveAccount.Visible = false; phCreateLogin.Visible = false; divSaveActions.Visible = false; nbSaveAccount.Title = "Success"; nbSaveAccount.Text = "The account has been saved for future use"; nbSaveAccount.NotificationBoxType = NotificationBoxType.Success; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Invalid Transaction"; nbSaveAccount.Text = "Sorry, the account information cannot be saved as there's not a valid transaction code to reference."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Invalid Gateway"; nbSaveAccount.Text = "Sorry, the financial gateway information for this type of transaction is not valid."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } else { nbSaveAccount.Title = "Missing Account Name"; nbSaveAccount.Text = "Please enter a name to use for this account."; nbSaveAccount.NotificationBoxType = NotificationBoxType.Danger; nbSaveAccount.Visible = true; } } }
/// <summary> /// Binds the saved accounts. /// </summary> private void BindSavedAccounts( RockContext rockContext, bool oneTime ) { rblSavedAccount.Items.Clear(); if ( _targetPerson != null ) { // Get the saved accounts for the currently logged in user var savedAccounts = new FinancialPersonSavedAccountService( rockContext ) .GetByPersonId( _targetPerson.Id ) .ToList(); // Find the saved accounts that are valid for the selected CC gateway var ccSavedAccountIds = new List<int>(); var ccCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ); if ( _ccGateway != null && _ccGatewayComponent != null && _ccGatewayComponent.SupportsSavedAccount( !oneTime ) && _ccGatewayComponent.SupportsSavedAccount( ccCurrencyType ) ) { ccSavedAccountIds = savedAccounts .Where( a => a.FinancialGatewayId == _ccGateway.Id && a.FinancialPaymentDetail != null && a.FinancialPaymentDetail.CurrencyTypeValueId == ccCurrencyType.Id ) .Select( a => a.Id ) .ToList(); } // Find the saved accounts that are valid for the selected ACH gateway var achSavedAccountIds = new List<int>(); var achCurrencyType = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ); if ( _achGateway != null && _achGatewayComponent != null && _achGatewayComponent.SupportsSavedAccount( !oneTime ) && _achGatewayComponent.SupportsSavedAccount( achCurrencyType ) ) { achSavedAccountIds = savedAccounts .Where( a => a.FinancialGatewayId == _achGateway.Id && a.FinancialPaymentDetail != null && a.FinancialPaymentDetail.CurrencyTypeValueId == achCurrencyType.Id ) .Select( a => a.Id ) .ToList(); } // Bind the accounts rblSavedAccount.DataSource = savedAccounts .Where( a => ccSavedAccountIds.Contains( a.Id ) || achSavedAccountIds.Contains( a.Id ) ) .OrderBy( a => a.Name ) .Select( a => new { Id = a.Id, Name = "Use " + a.Name + " (" + a.FinancialPaymentDetail.AccountNumberMasked + ")" } ).ToList(); rblSavedAccount.DataBind(); if ( rblSavedAccount.Items.Count > 0 ) { rblSavedAccount.Items.Add( new ListItem( "Use a different payment method", "0" ) ); if ( rblSavedAccount.SelectedValue == "" ) { rblSavedAccount.Items[0].Selected = true; } } } }
/// <summary> /// Gets the existing saved account. /// </summary> /// <param name="giveParameters">The give parameters.</param> /// <param name="person">The person.</param> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private FinancialPersonSavedAccount GetExistingSavedAccount( GiveParameters giveParameters, Person person, RockContext rockContext ) { if ( !giveParameters.SourceAccountId.HasValue ) { return null; } var savedAccount = new FinancialPersonSavedAccountService( rockContext ).Get( giveParameters.SourceAccountId.Value ); if ( savedAccount == null ) { GenerateResponse( HttpStatusCode.BadRequest, "The SourceAccountId passed is invalid" ); return null; } if ( !savedAccount.PersonAliasId.HasValue ) { GenerateResponse( HttpStatusCode.BadRequest, "The SourceAccount doesn't belong to anyone" ); return null; } if ( person.Aliases.All( a => a.Id != savedAccount.PersonAliasId.Value ) ) { GenerateResponse( HttpStatusCode.BadRequest, "The SourceAccount doesn't belong to the passed PersonId" ); return null; } return savedAccount; }