/// <summary> /// Gets the expression. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Type entityType, Data.IService serviceInstance, System.Linq.Expressions.ParameterExpression parameterExpression, string selection) { string[] selectionValues = selection.Split('|'); if (selectionValues.Length >= 1) { var accountGuids = selectionValues[0].Split(',').Select(a => a.AsGuid()).ToList(); var accountIds = new FinancialAccountService((RockContext)serviceInstance.Context).GetByGuids(accountGuids).Select(a => a.Id).ToList(); var qry = new FinancialScheduledTransactionDetailService((RockContext)serviceInstance.Context).Queryable() .Where(p => accountIds.Contains(p.AccountId)); Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.FinancialScheduledTransactionDetail>(qry, parameterExpression, "p"); return(extractedFilterExpression); } return(null); }
protected void lbSaveAccounts_Click(object sender, EventArgs e) { using (var rockContext = new RockContext()) { var txn = GetTransaction(rockContext); { decimal totalAmount = TransactionDetailsState.Select(d => d.Amount).ToList().Sum(); if (txn.TotalAmount != totalAmount) { nbError.Title = "Incorrect Amount"; nbError.Text = string.Format("<p>When updating account allocations, the total amount needs to remain the same as the original amount ({0}).</p>", txn.TotalAmount.FormatAsCurrency()); nbError.Visible = true; return; } var txnDetailService = new FinancialScheduledTransactionDetailService(rockContext); var accountService = new FinancialAccountService(rockContext); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where(a => a.ScheduledTransactionId.Equals(txn.Id)).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select(d => d.Guid).Contains(txnDetail.Guid) select txnDetail; bool accountChanges = deletedDetails.Any(); deletedDetails.ToList().ForEach(txnDetail => { txnDetailService.Delete(txnDetail); }); var changeSummary = new StringBuilder(); // Save Transaction Details foreach (var editorTxnDetail in TransactionDetailsState) { editorTxnDetail.Account = accountService.Get(editorTxnDetail.AccountId); // Add or Update the activity type var txnDetail = txn.ScheduledTransactionDetails.FirstOrDefault(d => d.Guid.Equals(editorTxnDetail.Guid)); if (txnDetail == null) { accountChanges = true; txnDetail = new FinancialScheduledTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.ScheduledTransactionDetails.Add(txnDetail); } else { if (txnDetail.AccountId != editorTxnDetail.AccountId || txnDetail.Amount != editorTxnDetail.Amount || txnDetail.Summary != editorTxnDetail.Summary) { accountChanges = true; } } changeSummary.AppendFormat("{0}: {1}", editorTxnDetail.Account != null ? editorTxnDetail.Account.Name : "?", editorTxnDetail.Amount.FormatAsCurrency()); changeSummary.AppendLine(); txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = editorTxnDetail.Amount; txnDetail.Summary = editorTxnDetail.Summary; } if (accountChanges) { // save changes rockContext.SaveChanges(); // Add a note about the change var noteType = NoteTypeCache.Read(Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = txn.Id; note.Caption = "Updated Transaction"; note.Text = changeSummary.ToString(); noteService.Add(note); } rockContext.SaveChanges(); } ShowView(txn); } } }
/// <summary> /// Processes the confirmation. /// </summary> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ProcessConfirmation( out string errorMessage ) { errorMessage = string.Empty; if ( string.IsNullOrWhiteSpace( TransactionCode ) ) { if ( Gateway == null ) { errorMessage = "There was a problem creating the payment gateway information"; return false; } using ( new UnitOfWorkScope() ) { var personService = new PersonService(); var transactionService = new FinancialScheduledTransactionService(); var transactionDetailService = new FinancialScheduledTransactionDetailService(); FinancialScheduledTransaction scheduledTransaction = null; if ( ScheduledTransactionId.HasValue ) { scheduledTransaction = transactionService.Get( ScheduledTransactionId.Value ); } if ( scheduledTransaction == null ) { errorMessage = "There was a problem getting the transaction information"; return false; } if ( scheduledTransaction.AuthorizedPerson == null ) { errorMessage = "There was a problem determining the person associated with the transaction"; return false; } // Get the payment schedule scheduledTransaction.TransactionFrequencyValueId = btnFrequency.SelectedValueAsId().Value; if ( dtpStartDate.SelectedDate.HasValue && dtpStartDate.SelectedDate > DateTime.Today ) { scheduledTransaction.StartDate = dtpStartDate.SelectedDate.Value; } else { scheduledTransaction.StartDate = DateTime.MinValue; } PaymentInfo paymentInfo = GetPaymentInfo( personService, scheduledTransaction ); if ( paymentInfo == null ) { errorMessage = "There was a problem creating the payment information"; return false; } else { } if ( Gateway.UpdateScheduledPayment( scheduledTransaction, paymentInfo, out errorMessage ) ) { var selectedAccountIds = SelectedAccounts .Where( a => a.Amount > 0 ) .Select( a => a.Id ).ToList(); var deletedAccounts = scheduledTransaction.ScheduledTransactionDetails .Where( a => !selectedAccountIds.Contains( a.AccountId ) ).ToList(); foreach ( var deletedAccount in deletedAccounts ) { scheduledTransaction.ScheduledTransactionDetails.Remove( deletedAccount ); transactionDetailService.Delete( deletedAccount, CurrentPersonId ); } foreach ( var account in SelectedAccounts ) { var detail = scheduledTransaction.ScheduledTransactionDetails .Where( d => d.AccountId == account.Id ).FirstOrDefault(); if ( detail == null ) { detail = new FinancialScheduledTransactionDetail(); detail.AccountId = account.Id; scheduledTransaction.ScheduledTransactionDetails.Add( detail ); } detail.Amount = account.Amount; } transactionService.Save( scheduledTransaction, CurrentPersonId ); ScheduleId = scheduledTransaction.GatewayScheduleId; TransactionCode = scheduledTransaction.TransactionCode; } else { return false; } tdTransactionCode.Description = TransactionCode; tdTransactionCode.Visible = !string.IsNullOrWhiteSpace( TransactionCode ); tdScheduleId.Description = ScheduleId; tdScheduleId.Visible = !string.IsNullOrWhiteSpace( ScheduleId ); return true; } } else { pnlDupWarning.Visible = true; return false; } }
/// <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> /// Processes the confirmation. /// </summary> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ProcessConfirmation( out string errorMessage ) { var rockContext = new RockContext(); errorMessage = string.Empty; if ( string.IsNullOrWhiteSpace( TransactionCode ) ) { if ( Gateway == null ) { errorMessage = "There was a problem creating the payment gateway information"; return false; } var personService = new PersonService( rockContext ); var transactionService = new FinancialScheduledTransactionService( rockContext ); var transactionDetailService = new FinancialScheduledTransactionDetailService( rockContext ); FinancialScheduledTransaction scheduledTransaction = null; if ( ScheduledTransactionId.HasValue ) { scheduledTransaction = transactionService.Get( ScheduledTransactionId.Value ); } if ( scheduledTransaction == null ) { errorMessage = "There was a problem getting the transaction information"; return false; } if ( scheduledTransaction.AuthorizedPerson == null ) { errorMessage = "There was a problem determining the person associated with the transaction"; return false; } var changeSummary = new StringBuilder(); // Get the payment schedule scheduledTransaction.TransactionFrequencyValueId = btnFrequency.SelectedValueAsId().Value; changeSummary.Append( DefinedValueCache.Read( scheduledTransaction.TransactionFrequencyValueId, rockContext ) ); if ( dtpStartDate.SelectedDate.HasValue && dtpStartDate.SelectedDate > RockDateTime.Today ) { scheduledTransaction.StartDate = dtpStartDate.SelectedDate.Value; changeSummary.AppendFormat( " starting {0}", scheduledTransaction.StartDate.ToShortDateString() ); } else { scheduledTransaction.StartDate = DateTime.MinValue; } changeSummary.AppendLine(); PaymentInfo paymentInfo = GetPaymentInfo( personService, scheduledTransaction ); if ( paymentInfo == null ) { errorMessage = "There was a problem creating the payment information"; return false; } else { } // If transaction is not active, attempt to re-activate it first if ( !scheduledTransaction.IsActive ) { if ( !transactionService.Reactivate( scheduledTransaction, out errorMessage ) ) { return false; } } if ( Gateway.UpdateScheduledPayment( scheduledTransaction, paymentInfo, out errorMessage ) ) { if ( paymentInfo.CurrencyTypeValue != null ) { changeSummary.Append( paymentInfo.CurrencyTypeValue.Value ); scheduledTransaction.CurrencyTypeValueId = paymentInfo.CurrencyTypeValue.Id; DefinedValueCache creditCardTypeValue = paymentInfo.CreditCardTypeValue; if ( creditCardTypeValue != null ) { changeSummary.AppendFormat( " - {0}", creditCardTypeValue.Value ); scheduledTransaction.CreditCardTypeValueId = creditCardTypeValue.Id; } else { scheduledTransaction.CreditCardTypeValueId = null; } changeSummary.AppendFormat( " {0}", paymentInfo.MaskedNumber ); changeSummary.AppendLine(); } var selectedAccountIds = SelectedAccounts .Where( a => a.Amount > 0 ) .Select( a => a.Id ).ToList(); var deletedAccounts = scheduledTransaction.ScheduledTransactionDetails .Where( a => !selectedAccountIds.Contains( a.AccountId ) ).ToList(); foreach ( var deletedAccount in deletedAccounts ) { scheduledTransaction.ScheduledTransactionDetails.Remove( deletedAccount ); transactionDetailService.Delete( deletedAccount ); } foreach ( var account in SelectedAccounts ) { var detail = scheduledTransaction.ScheduledTransactionDetails .Where( d => d.AccountId == account.Id ).FirstOrDefault(); if ( detail == null ) { detail = new FinancialScheduledTransactionDetail(); detail.AccountId = account.Id; scheduledTransaction.ScheduledTransactionDetails.Add( detail ); } detail.Amount = account.Amount; changeSummary.AppendFormat( "{0}: {1:C2}", account.Name, account.Amount ); changeSummary.AppendLine(); } rockContext.SaveChanges(); // Add a note about the change var noteTypeService = new NoteTypeService( rockContext ); var noteType = noteTypeService.Get( scheduledTransaction.TypeId, "Note" ); var noteService = new NoteService( rockContext ); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = scheduledTransaction.Id; note.Caption = "Updated Transaction"; note.Text = changeSummary.ToString(); noteService.Add( note ); rockContext.SaveChanges(); ScheduleId = scheduledTransaction.GatewayScheduleId; TransactionCode = scheduledTransaction.TransactionCode; if (transactionService.GetStatus( scheduledTransaction, out errorMessage )) { rockContext.SaveChanges(); } } else { return false; } tdTransactionCode.Description = TransactionCode; tdTransactionCode.Visible = !string.IsNullOrWhiteSpace( TransactionCode ); tdScheduleId.Description = ScheduleId; tdScheduleId.Visible = !string.IsNullOrWhiteSpace( ScheduleId ); return true; } else { pnlDupWarning.Visible = true; return false; } }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="usePaymentToken">if set to <c>true</c> [use payment token].</param> /// <param name="paymentToken">The payment token.</param> protected void UpdateScheduledPayment(bool usePaymentToken, string paymentToken = null) { var giftTerm = this.GetAttributeValue(AttributeKey.GiftTerm); if (dtpStartDate.SelectedDate <= RockDateTime.Today) { nbUpdateScheduledPaymentWarning.Visible = true; nbUpdateScheduledPaymentWarning.Text = string.Format("When scheduling a {0}, make sure the starting date is in the future (after today)", giftTerm.ToLower()); return; } var rockContext = new RockContext(); var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext); var financialScheduledTransactionDetailService = new FinancialScheduledTransactionDetailService(rockContext); Guid scheduledTransactionGuid = hfScheduledTransactionGuid.Value.AsGuid(); var financialScheduledTransaction = financialScheduledTransactionService.Get(scheduledTransactionGuid); financialScheduledTransaction.StartDate = dtpStartDate.SelectedDate.Value; financialScheduledTransaction.TransactionFrequencyValueId = ddlFrequency.SelectedValue.AsInteger(); ReferencePaymentInfo referencePaymentInfo; var person = financialScheduledTransaction.AuthorizedPersonAlias.Person; string errorMessage; var financialGateway = this.FinancialGateway; var financialGatewayComponent = this.FinancialGatewayComponent; var existingPaymentOrPersonSavedAccountId = rblExistingPaymentOrPersonSavedAccount.SelectedValue.AsInteger(); bool useExistingPaymentMethod = pnlUseExistingPaymentNoSavedAccounts.Visible || existingPaymentOrPersonSavedAccountId == 0; bool useSavedAccount = pnlUseExistingPaymentWithSavedAccounts.Visible && existingPaymentOrPersonSavedAccountId > 0; if (usePaymentToken) { referencePaymentInfo = new ReferencePaymentInfo(); referencePaymentInfo.FirstName = person.FirstName; referencePaymentInfo.LastName = person.LastName; referencePaymentInfo.UpdateAddressFieldsFromAddressControl(acBillingAddress); referencePaymentInfo.ReferenceNumber = paymentToken; var customerToken = financialGatewayComponent.CreateCustomerAccount(this.FinancialGateway, referencePaymentInfo, out errorMessage); if (errorMessage.IsNotNullOrWhiteSpace() || customerToken.IsNullOrWhiteSpace()) { nbMessage.NotificationBoxType = NotificationBoxType.Danger; nbMessage.Text = errorMessage ?? "Unknown Error"; nbMessage.Visible = true; return; } referencePaymentInfo.GatewayPersonIdentifier = customerToken; } else if (useExistingPaymentMethod) { // use save payment method as original transaction referencePaymentInfo = new ReferencePaymentInfo(); referencePaymentInfo.GatewayPersonIdentifier = financialScheduledTransaction.FinancialPaymentDetail.GatewayPersonIdentifier; referencePaymentInfo.FinancialPersonSavedAccountId = financialScheduledTransaction.FinancialPaymentDetail.FinancialPersonSavedAccountId; } else if (useSavedAccount) { var savedAccount = new FinancialPersonSavedAccountService(rockContext).Get(existingPaymentOrPersonSavedAccountId); if (savedAccount != null) { referencePaymentInfo = savedAccount.GetReferencePayment(); } else { // shouldn't happen throw new Exception("Unable to determine Saved Account"); } } else { // shouldn't happen throw new Exception("Unable to determine payment method"); } var selectedAccountAmounts = caapPromptForAccountAmounts.AccountAmounts.Where(a => a.Amount.HasValue && a.Amount.Value != 0).Select(a => new { a.AccountId, Amount = a.Amount.Value }).ToArray(); referencePaymentInfo.Amount = selectedAccountAmounts.Sum(a => a.Amount); var originalGatewayScheduleId = financialScheduledTransaction.GatewayScheduleId; try { financialScheduledTransaction.FinancialPaymentDetail.ClearPaymentInfo(); var successfullyUpdated = financialGatewayComponent.UpdateScheduledPayment(financialScheduledTransaction, referencePaymentInfo, out errorMessage); if (!successfullyUpdated) { nbMessage.NotificationBoxType = NotificationBoxType.Danger; nbMessage.Text = errorMessage ?? "Unknown Error"; nbMessage.Visible = true; return; } financialScheduledTransaction.FinancialPaymentDetail.SetFromPaymentInfo(referencePaymentInfo, financialGatewayComponent as GatewayComponent, rockContext); var selectedAccountIds = selectedAccountAmounts.Select(a => a.AccountId).ToArray(); var deletedTransactionDetails = financialScheduledTransaction.ScheduledTransactionDetails.ToList().Where(a => !selectedAccountIds.Contains(a.AccountId)).ToList(); foreach (var deletedTransactionDetail in deletedTransactionDetails) { financialScheduledTransaction.ScheduledTransactionDetails.Remove(deletedTransactionDetail); financialScheduledTransactionDetailService.Delete(deletedTransactionDetail); } foreach (var selectedAccountAmount in selectedAccountAmounts) { var scheduledTransactionDetail = financialScheduledTransaction.ScheduledTransactionDetails.FirstOrDefault(a => a.AccountId == selectedAccountAmount.AccountId); if (scheduledTransactionDetail == null) { scheduledTransactionDetail = new FinancialScheduledTransactionDetail(); scheduledTransactionDetail.AccountId = selectedAccountAmount.AccountId; financialScheduledTransaction.ScheduledTransactionDetails.Add(scheduledTransactionDetail); } scheduledTransactionDetail.Amount = selectedAccountAmount.Amount; } rockContext.SaveChanges(); Task.Run(() => ScheduledGiftWasModifiedMessage.PublishScheduledTransactionEvent(financialScheduledTransaction.Id, ScheduledGiftEventTypes.ScheduledGiftUpdated)); } catch (Exception) { // if the GatewayScheduleId was updated, but there was an exception, // make sure we save the financialScheduledTransaction record with the updated GatewayScheduleId so we don't orphan it if (financialScheduledTransaction.GatewayScheduleId.IsNotNullOrWhiteSpace() && (originalGatewayScheduleId != financialScheduledTransaction.GatewayScheduleId)) { rockContext.SaveChanges(); } throw; } var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); var finishLavaTemplate = this.GetAttributeValue(AttributeKey.FinishLavaTemplate); // re-fetch financialScheduledTransaction with a new RockContext from database to ensure that lazy loaded fields will be populated using (var rockContextForSummary = new RockContext()) { if (pnlHostedPaymentControl.Visible && hfSaveNewAccount.Value.AsInteger() == 1 && tbSaveAccount.Text.IsNotNullOrWhiteSpace()) { SaveNewFinancialPersonSavedAccount(financialScheduledTransaction); } financialScheduledTransaction = new FinancialScheduledTransactionService(rockContextForSummary).Get(scheduledTransactionGuid); mergeFields.Add("Transaction", financialScheduledTransaction); mergeFields.Add("Person", financialScheduledTransaction.AuthorizedPersonAlias.Person); mergeFields.Add("PaymentDetail", financialScheduledTransaction.FinancialPaymentDetail); mergeFields.Add("BillingLocation", financialScheduledTransaction.FinancialPaymentDetail.BillingLocation); pnlPromptForChanges.Visible = false; pnlTransactionSummary.Visible = true; lTransactionSummaryHTML.Text = finishLavaTemplate.ResolveMergeFields(mergeFields); } }
/// <summary> /// Handles the Click event of the btnSaveAccounts 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 btnSaveAccounts_Click(object sender, EventArgs e) { using (var rockContext = new RockContext()) { var financialScheduledTransaction = GetTransaction(rockContext); decimal totalAmount = TransactionDetailsState.Select(d => d.Amount).ToList().Sum(); if (financialScheduledTransaction.TotalAmount != totalAmount) { nbError.Title = "Incorrect Amount"; nbError.Text = string.Format("<p>When updating account allocations, the total amount needs to remain the same as the original amount ({0}).</p>", financialScheduledTransaction.TotalAmount.FormatAsCurrency()); nbError.Visible = true; return; } var txnDetailService = new FinancialScheduledTransactionDetailService(rockContext); var accountService = new FinancialAccountService(rockContext); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where(a => a.ScheduledTransactionId.Equals(financialScheduledTransaction.Id)).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select(d => d.Guid).Contains(txnDetail.Guid) select txnDetail; bool accountChanges = deletedDetails.Any(); deletedDetails.ToList().ForEach(txnDetail => { txnDetailService.Delete(txnDetail); }); // Save Transaction Details foreach (var editorTxnDetail in TransactionDetailsState) { editorTxnDetail.Account = accountService.Get(editorTxnDetail.AccountId); // Add or Update the activity type var financialTransactionDetail = financialScheduledTransaction.ScheduledTransactionDetails.FirstOrDefault(d => d.Guid.Equals(editorTxnDetail.Guid)); if (financialTransactionDetail == null) { accountChanges = true; financialTransactionDetail = new FinancialScheduledTransactionDetail(); financialTransactionDetail.Guid = editorTxnDetail.Guid; financialScheduledTransaction.ScheduledTransactionDetails.Add(financialTransactionDetail); } else { if (financialTransactionDetail.AccountId != editorTxnDetail.AccountId || financialTransactionDetail.Amount != editorTxnDetail.Amount || financialTransactionDetail.Summary != editorTxnDetail.Summary) { accountChanges = true; } } financialTransactionDetail.AccountId = editorTxnDetail.AccountId; financialTransactionDetail.Amount = editorTxnDetail.Amount; financialTransactionDetail.Summary = editorTxnDetail.Summary; } if (accountChanges) { // save changes rockContext.SaveChanges(); } ShowView(financialScheduledTransaction); } }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="usePaymentToken">if set to <c>true</c> [use payment token].</param> /// <param name="paymentToken">The payment token.</param> protected void UpdateScheduledPayment(bool usePaymentToken, string paymentToken = null) { var giftTerm = this.GetAttributeValue(AttributeKey.GiftTerm); if (dtpStartDate.SelectedDate <= RockDateTime.Today) { nbUpdateScheduledPaymentWarning.Visible = true; nbUpdateScheduledPaymentWarning.Text = string.Format("When scheduling a {0}, make sure the starting date is in the future (after today)", giftTerm.ToLower()); return; } var rockContext = new RockContext(); var financialScheduledTransactionService = new FinancialScheduledTransactionService(rockContext); var financialScheduledTransactionDetailService = new FinancialScheduledTransactionDetailService(rockContext); int scheduledTransactionId = hfScheduledTransactionId.Value.AsInteger(); var financialScheduledTransaction = financialScheduledTransactionService.Get(scheduledTransactionId); financialScheduledTransaction.StartDate = dtpStartDate.SelectedDate.Value; financialScheduledTransaction.TransactionFrequencyValueId = ddlFrequency.SelectedValue.AsInteger(); ReferencePaymentInfo referencePaymentInfo; var person = financialScheduledTransaction.AuthorizedPersonAlias.Person; string errorMessage; var financialGateway = this.FinancialGateway; var financialGatewayComponent = this.FinancialGatewayComponent; if (usePaymentToken) { referencePaymentInfo = new ReferencePaymentInfo(); referencePaymentInfo.FirstName = person.FirstName; referencePaymentInfo.LastName = person.LastName; referencePaymentInfo.UpdateAddressFieldsFromAddressControl(acBillingAddress); referencePaymentInfo.ReferenceNumber = paymentToken; var customerToken = financialGatewayComponent.CreateCustomerAccount(this.FinancialGateway, referencePaymentInfo, out errorMessage); if (errorMessage.IsNotNullOrWhiteSpace() || customerToken.IsNullOrWhiteSpace()) { nbMessage.NotificationBoxType = NotificationBoxType.Danger; nbMessage.Text = errorMessage ?? "Unknown Error"; nbMessage.Visible = true; return; } referencePaymentInfo.GatewayPersonIdentifier = customerToken; } else { var savedAccountId = ddlPersonSavedAccount.SelectedValue.AsInteger(); var savedAccount = new FinancialPersonSavedAccountService(rockContext).Get(savedAccountId); if (savedAccount != null) { referencePaymentInfo = savedAccount.GetReferencePayment(); } else { throw new Exception("Unable to determine Saved Account"); } } var selectedAccountAmounts = caapPromptForAccountAmounts.AccountAmounts.Where(a => a.Amount.HasValue && a.Amount.Value != 0).Select(a => new { a.AccountId, Amount = a.Amount.Value }).ToArray(); referencePaymentInfo.Amount = selectedAccountAmounts.Sum(a => a.Amount); var successfullyUpdated = financialGatewayComponent.UpdateScheduledPayment(financialScheduledTransaction, referencePaymentInfo, out errorMessage); if (!successfullyUpdated) { nbMessage.NotificationBoxType = NotificationBoxType.Danger; nbMessage.Text = errorMessage ?? "Unknown Error"; nbMessage.Visible = true; return; } financialScheduledTransaction.FinancialPaymentDetail.SetFromPaymentInfo(referencePaymentInfo, financialGatewayComponent as GatewayComponent, rockContext); var selectedAccountIds = selectedAccountAmounts.Select(a => a.AccountId).ToArray(); var deletedTransactionDetails = financialScheduledTransaction.ScheduledTransactionDetails.ToList().Where(a => !selectedAccountIds.Contains(a.AccountId)).ToList(); foreach (var deletedTransactionDetail in deletedTransactionDetails) { financialScheduledTransaction.ScheduledTransactionDetails.Remove(deletedTransactionDetail); financialScheduledTransactionDetailService.Delete(deletedTransactionDetail); } foreach (var selectedAccountAmount in selectedAccountAmounts) { var scheduledTransactionDetail = financialScheduledTransaction.ScheduledTransactionDetails.FirstOrDefault(a => a.AccountId == selectedAccountAmount.AccountId); if (scheduledTransactionDetail == null) { scheduledTransactionDetail = new FinancialScheduledTransactionDetail(); scheduledTransactionDetail.AccountId = selectedAccountAmount.AccountId; financialScheduledTransaction.ScheduledTransactionDetails.Add(scheduledTransactionDetail); } scheduledTransactionDetail.Amount = selectedAccountAmount.Amount; } rockContext.SaveChanges(); var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions { GetLegacyGlobalMergeFields = false }); var finishLavaTemplate = this.GetAttributeValue(AttributeKey.FinishLavaTemplate); mergeFields.Add("Transaction", financialScheduledTransaction); mergeFields.Add("Person", financialScheduledTransaction.AuthorizedPersonAlias.Person); mergeFields.Add("PaymentDetail", financialScheduledTransaction.FinancialPaymentDetail); mergeFields.Add("BillingLocation", financialScheduledTransaction.FinancialPaymentDetail.BillingLocation); pnlPromptForChanges.Visible = false; pnlTransactionSummary.Visible = true; lTransactionSummaryHTML.Text = finishLavaTemplate.ResolveMergeFields(mergeFields); }