/// <summary> /// Handles the Delete event of the grdFinancialTransactions 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 rGridTransactions_Delete(object sender, RowEventArgs e) { var financialTransactionService = new Rock.Model.FinancialTransactionService(); Grid grdTransactions = sender as Grid; Rock.Model.FinancialTransaction financialTransaction = financialTransactionService.Get((int)grdTransactions.DataKeys[e.RowIndex]["id"]); if (financialTransaction != null) { financialTransactionService.Delete(financialTransaction, CurrentPersonId); financialTransactionService.Save(financialTransaction, CurrentPersonId); } }
/// <summary> /// Handles the Delete event of the rGridTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param> protected void rGridTransactions_Delete(object sender, Rock.Web.UI.Controls.RowEventArgs e) { var financialTransactionService = new Rock.Model.FinancialTransactionService(); FinancialTransaction financialTransaction = financialTransactionService.Get((int)e.RowKeyValue); if (financialTransaction != null) { financialTransactionService.Delete(financialTransaction, CurrentPersonId); financialTransactionService.Save(financialTransaction, CurrentPersonId); } BindGrid(); }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var txnService = new FinancialTransactionService( rockContext ); var txnDetailService = new FinancialTransactionDetailService( rockContext ); var txnImageService = new FinancialTransactionImageService( rockContext ); var binaryFileService = new BinaryFileService( rockContext ); FinancialTransaction txn = null; int? txnId = hfTransactionId.Value.AsIntegerOrNull(); int? batchId = hfBatchId.Value.AsIntegerOrNull(); if ( txnId.HasValue ) { txn = txnService.Get( txnId.Value ); } if ( txn == null && batchId.HasValue ) { txn = new FinancialTransaction(); txnService.Add( txn ); txn.BatchId = batchId.Value; } if ( txn != null ) { txn.AuthorizedPersonId = ppAuthorizedPerson.PersonId; txn.TransactionDateTime = dtTransactionDateTime.SelectedDateTime; txn.TransactionTypeValueId = ddlTransactionType.SelectedValue.AsInteger(); txn.SourceTypeValueId = ddlSourceType.SelectedValueAsInt(); Guid? gatewayGuid = cpPaymentGateway.SelectedValueAsGuid(); if ( gatewayGuid.HasValue ) { var gatewayEntity = EntityTypeCache.Read( gatewayGuid.Value ); if ( gatewayEntity != null ) { txn.GatewayEntityTypeId = gatewayEntity.Id; } else { txn.GatewayEntityTypeId = null; } } else { txn.GatewayEntityTypeId = null; } txn.TransactionCode = tbTransactionCode.Text; txn.CurrencyTypeValueId = ddlCurrencyType.SelectedValueAsInt(); txn.CreditCardTypeValueId = ddlCreditCardType.SelectedValueAsInt(); txn.Summary = tbSummary.Text; if ( !Page.IsValid || !txn.IsValid ) { return; } foreach ( var txnDetail in TransactionDetailsState ) { if ( !txnDetail.IsValid ) { return; } } foreach ( var txnImage in TransactionImagesState ) { if ( !txnImage.IsValid ) { return; } } rockContext.WrapTransaction( () => { // Save the transaction rockContext.SaveChanges(); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select( d => d.Guid ).Contains( txnDetail.Guid ) select txnDetail; deletedDetails.ToList().ForEach( txnDetail => { txnDetailService.Delete( txnDetail ); } ); rockContext.SaveChanges(); // Save Transaction Details foreach ( var editorTxnDetail in TransactionDetailsState ) { // Add or Update the activity type var txnDetail = txn.TransactionDetails.FirstOrDefault( d => d.Guid.Equals( editorTxnDetail.Guid ) ); if ( txnDetail == null ) { txnDetail = new FinancialTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.TransactionDetails.Add( txnDetail ); } txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = editorTxnDetail.Amount; txnDetail.Summary = editorTxnDetail.Summary; } rockContext.SaveChanges(); // Remove any images that do not have a binary file foreach ( var txnImage in TransactionImagesState.Where( i => i.BinaryFileId == 0 ).ToList() ) { TransactionImagesState.Remove( txnImage ); } // Delete any transaction images that were removed var txnImagesInDB = txnImageService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); var deletedImages = from txnImage in txnImagesInDB where !TransactionImagesState.Select( d => d.Guid ).Contains( txnImage.Guid ) select txnImage; deletedImages.ToList().ForEach( txnImage => { txnImageService.Delete( txnImage ); } ); rockContext.SaveChanges(); // Save Transaction Images foreach ( var editorTxnImage in TransactionImagesState ) { // Add or Update the activity type var txnImage = txn.Images.FirstOrDefault( d => d.Guid.Equals( editorTxnImage.Guid ) ); if ( txnImage == null ) { txnImage = new FinancialTransactionImage(); txnImage.Guid = editorTxnImage.Guid; txn.Images.Add( txnImage ); } txnImage.BinaryFileId = editorTxnImage.BinaryFileId; txnImage.TransactionImageTypeValueId = editorTxnImage.TransactionImageTypeValueId; } rockContext.SaveChanges(); // Make sure updated binary files are not temporary var savedBinaryFileIds = txn.Images.Select( i => i.BinaryFileId ).ToList(); foreach ( var binaryFile in binaryFileService.Queryable().Where( f => savedBinaryFileIds.Contains( f.Id ) ) ) { binaryFile.IsTemporary = false; } // Delete any orphaned images var orphanedBinaryFileIds = BinaryFileIds.Where( f => !savedBinaryFileIds.Contains( f ) ); foreach ( var binaryFile in binaryFileService.Queryable().Where( f => orphanedBinaryFileIds.Contains( f.Id ) ) ) { binaryFileService.Delete( binaryFile ); } rockContext.SaveChanges(); } ); // Requery the batch to support EF navigation properties var savedTxn = GetTransaction( txn.Id ); ShowReadOnlyDetails( savedTxn ); } }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var txnService = new FinancialTransactionService( rockContext ); var txnDetailService = new FinancialTransactionDetailService( rockContext ); var txnImageService = new FinancialTransactionImageService( rockContext ); var binaryFileService = new BinaryFileService( rockContext ); FinancialTransaction txn = null; int? txnId = hfTransactionId.Value.AsIntegerOrNull(); int? batchId = hfBatchId.Value.AsIntegerOrNull(); if ( txnId.HasValue ) { txn = txnService.Get( txnId.Value ); } if ( txn == null ) { txn = new FinancialTransaction(); txnService.Add( txn ); txn.BatchId = batchId; } if ( txn != null ) { if ( ppAuthorizedPerson.PersonId.HasValue ) { txn.AuthorizedPersonAliasId = ppAuthorizedPerson.PersonAliasId; } txn.TransactionDateTime = dtTransactionDateTime.SelectedDateTime; txn.TransactionTypeValueId = ddlTransactionType.SelectedValue.AsInteger(); txn.SourceTypeValueId = ddlSourceType.SelectedValueAsInt(); Guid? gatewayGuid = cpPaymentGateway.SelectedValueAsGuid(); if ( gatewayGuid.HasValue ) { var gatewayEntity = EntityTypeCache.Read( gatewayGuid.Value ); if ( gatewayEntity != null ) { txn.GatewayEntityTypeId = gatewayEntity.Id; } else { txn.GatewayEntityTypeId = null; } } else { txn.GatewayEntityTypeId = null; } txn.TransactionCode = tbTransactionCode.Text; txn.CurrencyTypeValueId = ddlCurrencyType.SelectedValueAsInt(); txn.CreditCardTypeValueId = ddlCreditCardType.SelectedValueAsInt(); txn.Summary = tbSummary.Text; if ( !Page.IsValid || !txn.IsValid ) { return; } foreach ( var txnDetail in TransactionDetailsState ) { if ( !txnDetail.IsValid ) { return; } } rockContext.WrapTransaction( () => { // Save the transaction rockContext.SaveChanges(); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select( d => d.Guid ).Contains( txnDetail.Guid ) select txnDetail; deletedDetails.ToList().ForEach( txnDetail => { txnDetailService.Delete( txnDetail ); } ); rockContext.SaveChanges(); // Save Transaction Details foreach ( var editorTxnDetail in TransactionDetailsState ) { // Add or Update the activity type var txnDetail = txn.TransactionDetails.FirstOrDefault( d => d.Guid.Equals( editorTxnDetail.Guid ) ); if ( txnDetail == null ) { txnDetail = new FinancialTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.TransactionDetails.Add( txnDetail ); } txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = UseSimpleAccountMode ? tbSingleAccountAmount.Text.AsDecimal() : editorTxnDetail.Amount; txnDetail.Summary = editorTxnDetail.Summary; } rockContext.SaveChanges(); // Delete any transaction images that were removed var orphanedBinaryFileIds = new List<int>(); var txnImagesInDB = txnImageService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); foreach ( var txnImage in txnImagesInDB.Where( i => !TransactionImagesState.Contains( i.BinaryFileId ) ) ) { orphanedBinaryFileIds.Add( txnImage.BinaryFileId ); txnImageService.Delete( txnImage ); } // Save Transaction Images int imageOrder = 0; foreach ( var binaryFileId in TransactionImagesState ) { // Add or Update the activity type var txnImage = txnImagesInDB.FirstOrDefault( i => i.BinaryFileId == binaryFileId ); if ( txnImage == null ) { txnImage = new FinancialTransactionImage(); txnImage.TransactionId = txn.Id; txn.Images.Add( txnImage ); } txnImage.BinaryFileId = binaryFileId; txnImage.Order = imageOrder; imageOrder++; } rockContext.SaveChanges(); // Make sure updated binary files are not temporary foreach ( var binaryFile in binaryFileService.Queryable().Where( f => TransactionImagesState.Contains( f.Id ) ) ) { binaryFile.IsTemporary = false; } // Delete any orphaned images foreach ( var binaryFile in binaryFileService.Queryable().Where( f => orphanedBinaryFileIds.Contains( f.Id ) ) ) { binaryFileService.Delete( binaryFile ); } rockContext.SaveChanges(); } ); // Save selected options to session state in order to prefill values for next added txn Session["NewTxnDefault_BatchId"] = txn.BatchId; Session["NewTxnDefault_TransactionDateTime"] = txn.TransactionDateTime; Session["NewTxnDefault_TransactionType"] = txn.TransactionTypeValueId; Session["NewTxnDefault_SourceType"] = txn.SourceTypeValueId; Session["NewTxnDefault_CurrencyType"] = txn.CurrencyTypeValueId; Session["NewTxnDefault_CreditCardType"] = txn.CreditCardTypeValueId; if ( TransactionDetailsState.Count() == 1 ) { Session["NewTxnDefault_Account"] = TransactionDetailsState.First().AccountId; } else { Session.Remove("NewTxnDefault_Account"); } // Requery the batch to support EF navigation properties var savedTxn = GetTransaction( txn.Id ); ShowReadOnlyDetails( savedTxn ); } }
/// <summary> /// Handles the Delete event of the gTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param> protected void gTransactions_Delete( object sender, Rock.Web.UI.Controls.RowEventArgs e ) { var rockContext = new RockContext(); var transactionService = new FinancialTransactionService( rockContext ); var transaction = transactionService.Get( e.RowKeyId ); if ( transaction != null ) { string errorMessage; if ( !transactionService.CanDelete( transaction, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } transactionService.Delete( transaction ); rockContext.SaveChanges(); RockPage.UpdateBlocks( "~/Blocks/Finance/BatchDetail.ascx" ); } BindGrid(); }
/// <summary> /// Executes this instance. /// </summary> public void Execute() { using ( var rockContext = new RockContext() ) { var service = new FinancialTransactionService( rockContext ); foreach ( int transactionId in TransactionIds ) { var transaction = service.Get( transactionId ); if ( transaction != null && transaction.AuthorizedPersonAlias != null && transaction.AuthorizedPersonAlias.Person != null ) { var person = transaction.AuthorizedPersonAlias.Person; // setup merge fields var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); mergeFields.Add( "Person", person ); decimal totalAmount = 0; List<Dictionary<String, object>> accountAmounts = new List<Dictionary<String, object>>(); foreach ( var detail in transaction.TransactionDetails ) { if ( detail.Account != null && detail.Amount > 0 ) { var accountAmount = new Dictionary<String, object>(); accountAmount.Add( "AccountId", detail.Account.Id ); accountAmount.Add( "AccountName", detail.Account.Name ); accountAmount.Add( "Amount", detail.Amount ); accountAmounts.Add( accountAmount ); totalAmount += detail.Amount; } } mergeFields.Add( "TotalAmount", totalAmount ); mergeFields.Add( "GaveAnonymous", "False" ); mergeFields.Add( "ReceiptEmail", person.Email ); mergeFields.Add( "ReceiptEmailed", true ); mergeFields.Add( "LastName", person.LastName ); mergeFields.Add( "FirstNames", person.NickName ); mergeFields.Add( "TransactionCode", transaction.TransactionCode ); mergeFields.Add( "Transaction", transaction ); mergeFields.Add( "Amounts", accountAmounts ); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "ExternalApplicationRoot" ); var recipients = new List<RecipientData>(); recipients.Add( new RecipientData( person.Email, mergeFields ) ); Email.Send( SystemEmailGuid, recipients, appRoot ); } } } }
private void BindGrid() { TransactionSearchValue searchValue = GetSearchValue(); var transactionService = new FinancialTransactionService(); grdTransactions.DataSource = transactionService.Get( searchValue ).ToList(); grdTransactions.DataBind(); }
/// <summary> /// Handles the Click event of the btnNext 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 btnNext_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var financialTransactionService = new FinancialTransactionService( rockContext ); var financialTransactionDetailService = new FinancialTransactionDetailService( rockContext ); var financialPersonBankAccountService = new FinancialPersonBankAccountService( rockContext ); var financialTransaction = financialTransactionService.Get( hfTransactionId.Value.AsInteger() ); // set the AuthorizedPersonId (the person who wrote the check) to the if the SelectNew person (if selected) or person selected in the drop down (if there is somebody selected) int? authorizedPersonId = ppSelectNew.PersonId ?? ddlIndividual.SelectedValue.AsIntegerOrNull(); var accountNumberSecured = hfCheckMicrHashed.Value; if ( cbTotalAmount.Text.AsDecimalOrNull().HasValue && !authorizedPersonId.HasValue ) { nbSaveError.Text = "Transaction must be matched to a person when the amount is specified."; nbSaveError.Visible = true; return; } // if the transaction was previously matched, but user unmatched it, save it as an unmatched transaction and clear out the detail records (we don't want an unmatched transaction to have detail records) if ( financialTransaction != null && financialTransaction.AuthorizedPersonId.HasValue && !authorizedPersonId.HasValue ) { financialTransaction.AuthorizedPersonId = null; foreach ( var detail in financialTransaction.TransactionDetails ) { financialTransactionDetailService.Delete( detail ); } rockContext.SaveChanges(); // if the transaction was unmatched, clear out the ProcessedBy fields since we didn't match the check and are moving on to process another transaction MarkTransactionAsNotProcessedByCurrentUser( hfTransactionId.Value.AsInteger() ); } // if the transaction is matched to somebody, attempt to save it. Otherwise, if the transaction was previously matched, but user unmatched it, save it as an unmatched transaction if ( financialTransaction != null && authorizedPersonId.HasValue ) { if ( string.IsNullOrWhiteSpace( accountNumberSecured ) ) { // should be showing already, but just in case nbNoMicrWarning.Visible = true; return; } if ( cbTotalAmount.Text.AsDecimalOrNull() == null ) { nbSaveError.Text = "Total amount must be allocated to accounts."; nbSaveError.Visible = true; return; } var financialPersonBankAccount = financialPersonBankAccountService.Queryable().Where( a => a.AccountNumberSecured == accountNumberSecured && a.PersonId == authorizedPersonId ).FirstOrDefault(); if ( financialPersonBankAccount == null ) { financialPersonBankAccount = new FinancialPersonBankAccount(); financialPersonBankAccount.PersonId = authorizedPersonId.Value; financialPersonBankAccount.AccountNumberSecured = accountNumberSecured; var checkMicrClearText = Encryption.DecryptString( financialTransaction.CheckMicrEncrypted ); var parts = checkMicrClearText.Split( '_' ); if ( parts.Length >= 2 ) { financialPersonBankAccount.AccountNumberMasked = parts[1].Masked(); } financialPersonBankAccountService.Add( financialPersonBankAccount ); } financialTransaction.AuthorizedPersonId = authorizedPersonId; // just in case this transaction is getting re-edited either by the same user, or somebody else, clean out any existing TransactionDetail records foreach ( var detail in financialTransaction.TransactionDetails.ToList() ) { financialTransactionDetailService.Delete( detail ); } foreach ( var accountBox in rptAccounts.ControlsOfTypeRecursive<CurrencyBox>() ) { var amount = accountBox.Text.AsDecimalOrNull(); if ( amount.HasValue && amount.Value >= 0 ) { var financialTransactionDetail = new FinancialTransactionDetail(); financialTransactionDetail.TransactionId = financialTransaction.Id; financialTransactionDetail.AccountId = accountBox.Attributes["data-account-id"].AsInteger(); financialTransactionDetail.Amount = amount.Value; financialTransactionDetailService.Add( financialTransactionDetail ); } } financialTransaction.ProcessedByPersonAliasId = this.CurrentPersonAlias.Id; financialTransaction.ProcessedDateTime = RockDateTime.Now; rockContext.SaveChanges(); } else { // if the transaction was not matched, clear out the ProcessedBy fields since we didn't match the check and are moving on to process another transaction MarkTransactionAsNotProcessedByCurrentUser( hfTransactionId.Value.AsInteger() ); } NavigateToTransaction( Direction.Next ); }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var txnService = new FinancialTransactionService( rockContext ); var txnDetailService = new FinancialTransactionDetailService( rockContext ); var txnImageService = new FinancialTransactionImageService( rockContext ); var binaryFileService = new BinaryFileService( rockContext ); FinancialTransaction txn = null; int? txnId = hfTransactionId.Value.AsIntegerOrNull(); int? batchId = hfBatchId.Value.AsIntegerOrNull(); var changes = new List<string>(); if ( txnId.HasValue ) { txn = txnService.Get( txnId.Value ); } if ( txn == null ) { txn = new FinancialTransaction(); txnService.Add( txn ); txn.BatchId = batchId; changes.Add( "Created transaction" ); } if ( txn != null ) { if ( txn.FinancialPaymentDetail == null ) { txn.FinancialPaymentDetail = new FinancialPaymentDetail(); } string newPerson = ppAuthorizedPerson.PersonName; if ( batchId.HasValue ) { if ( !txn.AuthorizedPersonAliasId.Equals( ppAuthorizedPerson.PersonAliasId ) ) { string prevPerson = ( txn.AuthorizedPersonAlias != null && txn.AuthorizedPersonAlias.Person != null ) ? txn.AuthorizedPersonAlias.Person.FullName : string.Empty; History.EvaluateChange( changes, "Person", prevPerson, newPerson ); } History.EvaluateChange( changes, "Date/Time", txn.TransactionDateTime, dtTransactionDateTime.SelectedDateTime ); History.EvaluateChange( changes, "Type", GetDefinedValue( txn.TransactionTypeValueId ), GetDefinedValue( ddlTransactionType.SelectedValue.AsInteger() ) ); History.EvaluateChange( changes, "Source", GetDefinedValue( txn.SourceTypeValueId ), GetDefinedValue( ddlSourceType.SelectedValueAsInt() ) ); if ( !txn.FinancialGatewayId.Equals( gpPaymentGateway.SelectedValueAsInt() ) ) { History.EvaluateChange( changes, "Gateway", GetFinancialGatewayName( txn.FinancialGatewayId, rockContext ), GetFinancialGatewayName( gpPaymentGateway.SelectedValueAsInt(), rockContext ) ); } History.EvaluateChange( changes, "Transaction Code", txn.TransactionCode, tbTransactionCode.Text ); History.EvaluateChange( changes, "Currency Type", GetDefinedValue( txn.FinancialPaymentDetail.CurrencyTypeValueId ), GetDefinedValue( ddlCurrencyType.SelectedValueAsInt() ) ); History.EvaluateChange( changes, "Credit Card Type", GetDefinedValue( txn.FinancialPaymentDetail.CreditCardTypeValueId ), GetDefinedValue( ddlCreditCardType.SelectedValueAsInt() ) ); History.EvaluateChange( changes, "Summary", txn.Summary, tbSummary.Text ); History.EvaluateChange( changes, "Is Refund", ( txn.RefundDetails != null ), cbIsRefund.Checked ); } txn.AuthorizedPersonAliasId = ppAuthorizedPerson.PersonAliasId; txn.TransactionDateTime = dtTransactionDateTime.SelectedDateTime; txn.TransactionTypeValueId = ddlTransactionType.SelectedValue.AsInteger(); txn.SourceTypeValueId = ddlSourceType.SelectedValueAsInt(); txn.FinancialGatewayId = gpPaymentGateway.SelectedValueAsInt(); txn.TransactionCode = tbTransactionCode.Text; txn.FinancialPaymentDetail.CurrencyTypeValueId = ddlCurrencyType.SelectedValueAsInt(); txn.FinancialPaymentDetail.CreditCardTypeValueId = ddlCreditCardType.SelectedValueAsInt(); txn.Summary = tbSummary.Text; decimal totalAmount = TransactionDetailsState.Select( d => d.Amount ).ToList().Sum(); if ( cbIsRefund.Checked && totalAmount > 0 ) { nbErrorMessage.Title = "Incorrect Refund Amount"; nbErrorMessage.Text = "<p>A refund should have a negative amount. Please unselect the refund option, or change amounts to be negative values.</p>"; nbErrorMessage.Visible = true; return; } if ( cbIsRefund.Checked ) { if ( txn.RefundDetails != null ) { txn.RefundDetails = new FinancialTransactionRefund(); } txn.RefundDetails.RefundReasonValueId = ddlRefundReasonEdit.SelectedValueAsId(); txn.RefundDetails.RefundReasonSummary = tbRefundSummaryEdit.Text; } if ( !Page.IsValid || !txn.IsValid ) { return; } foreach ( var txnDetail in TransactionDetailsState ) { if ( !txnDetail.IsValid ) { return; } } rockContext.WrapTransaction( () => { // Save the transaction rockContext.SaveChanges(); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select( d => d.Guid ).Contains( txnDetail.Guid ) select txnDetail; deletedDetails.ToList().ForEach( txnDetail => { if ( batchId.HasValue ) { History.EvaluateChange( changes, txnDetail.Account != null ? txnDetail.Account.Name : "Unknown", txnDetail.Amount.FormatAsCurrency(), string.Empty ); } txnDetailService.Delete( txnDetail ); } ); // Save Transaction Details foreach ( var editorTxnDetail in TransactionDetailsState ) { string oldAccountName = string.Empty; string newAccountName = string.Empty; decimal oldAmount = 0.0M; decimal newAmount = 0.0M; // Add or Update the activity type var txnDetail = txn.TransactionDetails.FirstOrDefault( d => d.Guid.Equals( editorTxnDetail.Guid ) ); if ( txnDetail != null ) { oldAccountName = AccountName( txnDetail.AccountId ); oldAmount = txnDetail.Amount; } else { txnDetail = new FinancialTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.TransactionDetails.Add( txnDetail ); } newAccountName = AccountName( editorTxnDetail.AccountId ); newAmount = UseSimpleAccountMode ? tbSingleAccountAmount.Text.AsDecimal() : editorTxnDetail.Amount; if ( batchId.HasValue ) { if ( string.IsNullOrWhiteSpace(oldAccountName) ) { History.EvaluateChange( changes, newAccountName, string.Empty, newAmount.FormatAsCurrency() ); } else { if ( oldAccountName == newAccountName ) { if ( oldAmount != newAmount ) { History.EvaluateChange( changes, oldAccountName, oldAmount.FormatAsCurrency(), newAmount.FormatAsCurrency() ); } } else { History.EvaluateChange( changes, oldAccountName, oldAmount.FormatAsCurrency(), string.Empty ); History.EvaluateChange( changes, newAccountName, string.Empty, newAmount.FormatAsCurrency() ); } } } txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = newAmount; txnDetail.Summary = editorTxnDetail.Summary; if ( editorTxnDetail.AttributeValues != null ) { txnDetail.LoadAttributes(); txnDetail.AttributeValues = editorTxnDetail.AttributeValues; rockContext.SaveChanges(); txnDetail.SaveAttributeValues( rockContext ); } } // Delete any transaction images that were removed var orphanedBinaryFileIds = new List<int>(); var txnImagesInDB = txnImageService.Queryable().Where( a => a.TransactionId.Equals( txn.Id ) ).ToList(); foreach ( var txnImage in txnImagesInDB.Where( i => !TransactionImagesState.Contains( i.BinaryFileId ) ) ) { changes.Add( "Removed Image" ); orphanedBinaryFileIds.Add( txnImage.BinaryFileId ); txnImageService.Delete( txnImage ); } // Save Transaction Images int imageOrder = 0; foreach ( var binaryFileId in TransactionImagesState ) { // Add or Update the activity type var txnImage = txnImagesInDB.FirstOrDefault( i => i.BinaryFileId == binaryFileId ); if ( txnImage == null ) { changes.Add( "Added Image" ); txnImage = new FinancialTransactionImage(); txnImage.TransactionId = txn.Id; txn.Images.Add( txnImage ); } else { if ( txnImage.BinaryFileId != binaryFileId ) { changes.Add( "Updated Image" ); } } txnImage.BinaryFileId = binaryFileId; txnImage.Order = imageOrder; imageOrder++; } rockContext.SaveChanges(); // Make sure updated binary files are not temporary foreach ( var binaryFile in binaryFileService.Queryable().Where( f => TransactionImagesState.Contains( f.Id ) ) ) { binaryFile.IsTemporary = false; } // Delete any orphaned images foreach ( var binaryFile in binaryFileService.Queryable().Where( f => orphanedBinaryFileIds.Contains( f.Id ) ) ) { binaryFileService.Delete( binaryFile ); } // Update any attributes txn.LoadAttributes(rockContext); txn.FinancialPaymentDetail.LoadAttributes(rockContext); Helper.GetEditValues(phAttributeEdits, txn); Helper.GetEditValues(phPaymentAttributeEdits, txn.FinancialPaymentDetail); // If the transaction is associated with a batch, update that batch's history if ( batchId.HasValue ) { HistoryService.SaveChanges( rockContext, typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), batchId.Value, changes, !string.IsNullOrWhiteSpace( newPerson ) ? newPerson : string.Format( "Transaction Id:{0}", txn.Id ), typeof( FinancialTransaction ), txn.Id ); } rockContext.SaveChanges(); txn.SaveAttributeValues(rockContext); txn.FinancialPaymentDetail.SaveAttributeValues(rockContext); } ); // Save selected options to session state in order to prefill values for next added txn Session["NewTxnDefault_BatchId"] = txn.BatchId; Session["NewTxnDefault_TransactionDateTime"] = txn.TransactionDateTime; Session["NewTxnDefault_TransactionType"] = txn.TransactionTypeValueId; Session["NewTxnDefault_SourceType"] = txn.SourceTypeValueId; Session["NewTxnDefault_CurrencyType"] = txn.FinancialPaymentDetail.CurrencyTypeValueId; Session["NewTxnDefault_CreditCardType"] = txn.FinancialPaymentDetail.CreditCardTypeValueId; if ( TransactionDetailsState.Count() == 1 ) { Session["NewTxnDefault_Account"] = TransactionDetailsState.First().AccountId; } else { Session.Remove("NewTxnDefault_Account"); } // Requery the batch to support EF navigation properties var savedTxn = GetTransaction( txn.Id ); if ( savedTxn != null ) { savedTxn.LoadAttributes(); savedTxn.FinancialPaymentDetail.LoadAttributes(); ShowReadOnlyDetails( savedTxn ); } } }
/// <summary> /// Handles the SaveClick event of the mdRefund 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 mdRefund_SaveClick( object sender, EventArgs e ) { decimal refundAmount = tbRefundAmount.Text.AsDecimal(); if ( refundAmount > 0.0m ) { int? txnId = hfTransactionId.Value.AsIntegerOrNull(); if ( txnId.HasValue ) { using ( var rockContext = new RockContext() ) { var txnService = new FinancialTransactionService( rockContext ); var txn = txnService.Get( txnId.Value ); if ( txn != null && txn.Batch != null ) { FinancialTransaction refundTxn = null; if ( !string.IsNullOrWhiteSpace( txn.TransactionCode ) && txn.FinancialGateway != null && cbProcess.Visible && cbProcess.Checked ) { var gateway = txn.FinancialGateway.GetGatewayComponent(); if ( gateway != null ) { string errorMessage = string.Empty; refundTxn = gateway.Credit( txn, refundAmount, tbRefundSummary.Text, out errorMessage ); if ( refundTxn == null ) { nbRefundError.Title = "Refund Error"; nbRefundError.Text = string.Format( "<p>{0}</p>", errorMessage ); nbRefundError.Visible = true; return; } } else { nbRefundError.Title = "Gateway Error"; nbRefundError.Text = "<p>Transaction has a valid gateway, but we could not use it.</p>"; nbRefundError.Visible = true; return; } } else { refundTxn = new FinancialTransaction(); } refundTxn.AuthorizedPersonAliasId = txn.AuthorizedPersonAliasId; refundTxn.TransactionDateTime = RockDateTime.Now; refundTxn.FinancialGatewayId = txn.FinancialGatewayId; refundTxn.TransactionTypeValueId = txn.TransactionTypeValueId; if ( txn.FinancialPaymentDetail != null ) { refundTxn.FinancialPaymentDetail = new FinancialPaymentDetail(); refundTxn.FinancialPaymentDetail.AccountNumberMasked = txn.FinancialPaymentDetail.AccountNumberMasked; refundTxn.FinancialPaymentDetail.BillingLocationId = txn.FinancialPaymentDetail.BillingLocationId; refundTxn.FinancialPaymentDetail.CreditCardTypeValueId = txn.FinancialPaymentDetail.CreditCardTypeValueId; refundTxn.FinancialPaymentDetail.CurrencyTypeValueId = txn.FinancialPaymentDetail.CurrencyTypeValueId; refundTxn.FinancialPaymentDetail.ExpirationMonthEncrypted = txn.FinancialPaymentDetail.ExpirationMonthEncrypted; refundTxn.FinancialPaymentDetail.ExpirationYearEncrypted = txn.FinancialPaymentDetail.ExpirationYearEncrypted; refundTxn.FinancialPaymentDetail.NameOnCardEncrypted = txn.FinancialPaymentDetail.NameOnCardEncrypted; } decimal remBalance = refundAmount; foreach ( var account in txn.TransactionDetails.Where( a => a.Amount > 0 ) ) { var transactionDetail = new FinancialTransactionDetail(); transactionDetail.AccountId = account.AccountId; transactionDetail.EntityId = account.EntityId; transactionDetail.EntityTypeId = account.EntityTypeId; refundTxn.TransactionDetails.Add( transactionDetail ); if ( remBalance >= account.Amount ) { transactionDetail.Amount = 0 - account.Amount; remBalance -= account.Amount; } else { transactionDetail.Amount = 0 - remBalance; remBalance = 0.0m; } if ( remBalance <= 0.0m ) { break; } } if ( remBalance > 0 && refundTxn.TransactionDetails.Any() ) { refundTxn.TransactionDetails.Last().Amount += remBalance; } var registrationEntityType = EntityTypeCache.Read( typeof( Rock.Model.Registration ) ); if ( registrationEntityType != null ) { foreach ( var transactionDetail in refundTxn.TransactionDetails .Where( d => d.EntityTypeId.HasValue && d.EntityTypeId.Value == registrationEntityType.Id && d.EntityId.HasValue ) ) { var registrationChanges = new List<string>(); registrationChanges.Add( string.Format( "Processed refund for {0}.", transactionDetail.Amount.FormatAsCurrency() ) ); HistoryService.SaveChanges( rockContext, typeof( Registration ), Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(), transactionDetail.EntityId.Value, registrationChanges ); } } refundTxn.RefundDetails = new FinancialTransactionRefund(); refundTxn.RefundDetails.RefundReasonValueId = ddlRefundReason.SelectedValueAsId(); refundTxn.RefundDetails.RefundReasonSummary = tbRefundSummary.Text; refundTxn.RefundDetails.OriginalTransactionId = txn.Id; string batchName = txn.Batch.Name; string suffix = GetAttributeValue( "RefundBatchNameSuffix" ); if ( !string.IsNullOrWhiteSpace( suffix ) && !batchName.EndsWith( suffix ) ) { batchName += suffix; } // Get the batch var batchService = new FinancialBatchService( rockContext ); TimeSpan timespan = new TimeSpan(); if ( txn.FinancialGateway != null ) { timespan = txn.FinancialGateway.GetBatchTimeOffset(); } var batch = batchService.GetByNameAndDate( batchName, refundTxn.TransactionDateTime.Value, timespan ); decimal controlAmount = batch.ControlAmount + refundTxn.TotalAmount; batch.ControlAmount = controlAmount; refundTxn.BatchId = batch.Id; batch.Transactions.Add( refundTxn ); rockContext.SaveChanges(); var updatedTxn = GetTransaction( txn.Id ); if ( updatedTxn != null ) { updatedTxn.LoadAttributes( rockContext ); updatedTxn.FinancialPaymentDetail.LoadAttributes(rockContext); ShowReadOnlyDetails( updatedTxn ); } } else { nbRefundError.Title = "Transaction Error"; nbRefundError.Text = "<p>Existing transaction does not hava a valid batch.</p>"; nbRefundError.Visible = true; return; } } } } HideDialog(); }
/// <summary> /// Shows the refund dialog. /// </summary> private void ShowRefundDialog() { int? txnId = hfTransactionId.Value.AsIntegerOrNull(); if ( txnId.HasValue ) { using ( var rockContext = new RockContext() ) { var txnService = new FinancialTransactionService( rockContext ); var txn = txnService.Get( txnId.Value ); if ( txn != null ) { var totalAmount = txn.TotalAmount; var otherAmounts = new FinancialTransactionDetailService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.Transaction != null && ( ( txn.TransactionCode != null && txn.TransactionCode != "" && d.Transaction.TransactionCode == txn.TransactionCode && d.TransactionId != txn.Id ) || ( d.Transaction.RefundDetails != null && d.Transaction.RefundDetails.OriginalTransactionId == txn.Id ) ) ) .Select( d => d.Amount ) .ToList() .Sum(); totalAmount += otherAmounts; tbRefundAmount.Text = ( totalAmount > 0.0m ? totalAmount : 0.0m ).ToString( "N2" ); ddlRefundReason.SelectedIndex = -1; tbRefundSummary.Text = string.Empty; bool hasGateway = !string.IsNullOrWhiteSpace( txn.TransactionCode ) && txn.FinancialGateway != null; cbProcess.Visible = hasGateway; cbProcess.Checked = hasGateway; ShowDialog( "REFUND" ); _focusControl = tbRefundAmount; } } } }
/// <summary> /// Handles the Delete event of the rGridTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param> protected void rGridTransactions_Delete( object sender, Rock.Web.UI.Controls.RowEventArgs e ) { var financialTransactionService = new Rock.Model.FinancialTransactionService(); FinancialTransaction financialTransaction = financialTransactionService.Get( (int)e.RowKeyValue ); if ( financialTransaction != null ) { financialTransactionService.Delete( financialTransaction, CurrentPersonId ); financialTransactionService.Save( financialTransaction, CurrentPersonId ); } BindGrid(); }
/// <summary> /// Handles the Click event of the btnSaveFinancialTransaction 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 lbSaveTransaction_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var financialTransactionService = new Rock.Model.FinancialTransactionService(rockContext); Rock.Model.FinancialTransaction financialTransaction = null; int financialTransactionId = !string.IsNullOrEmpty(hfIdTransValue.Value) ? int.Parse(hfIdTransValue.Value) : 0; // null if not associated with a batch int?batchId = hfBatchId.Value.AsInteger(); if (financialTransactionId == 0) { financialTransaction = new Rock.Model.FinancialTransaction(); financialTransactionService.Add(financialTransaction); financialTransaction.BatchId = batchId; } else { financialTransaction = financialTransactionService.Get(financialTransactionId); } if (ppAuthorizedPerson.PersonId != null) { financialTransaction.AuthorizedPersonId = ppAuthorizedPerson.PersonId; } else { financialTransaction.AuthorizedPersonId = null; } if (ddlCurrencyType.SelectedItem.ToString() == "Credit Card") { financialTransaction.CreditCardTypeValueId = int.Parse(ddlCreditCardType.SelectedValue); } else { financialTransaction.CreditCardTypeValueId = null; } financialTransaction.CurrencyTypeValueId = int.Parse(ddlCurrencyType.SelectedValue); if (!string.IsNullOrEmpty(ddlPaymentGateway.SelectedValue)) { var gatewayEntity = Rock.Web.Cache.EntityTypeCache.Read(new Guid(ddlPaymentGateway.SelectedValue)); if (gatewayEntity != null) { financialTransaction.GatewayEntityTypeId = gatewayEntity.Id; } } financialTransaction.SourceTypeValueId = int.Parse(ddlSourceType.SelectedValue); financialTransaction.TransactionTypeValueId = int.Parse(ddlTransactionType.SelectedValue); financialTransaction.Summary = tbSummary.Text; financialTransaction.TransactionCode = tbTransactionCode.Text; financialTransaction.TransactionDateTime = dtTransactionDateTime.SelectedDateTime; rockContext.SaveChanges(); if (batchId != null) { Dictionary <string, string> qryString = new Dictionary <string, string>(); qryString["financialBatchid"] = hfBatchId.Value; NavigateToParentPage(qryString); } else { NavigateToParentPage(); } }
/// <summary> /// Marks the transaction as not processed by the current user /// </summary> /// <param name="transactionId">The transaction identifier.</param> private void MarkTransactionAsNotProcessedByCurrentUser( int transactionId ) { var rockContext = new RockContext(); var financialTransactionService = new FinancialTransactionService( rockContext ); var financialTransaction = financialTransactionService.Get( transactionId ); if ( financialTransaction != null && financialTransaction.ProcessedByPersonAliasId == CurrentPersonAliasId && financialTransaction.AuthorizedPersonAliasId == null ) { // if the current user marked this as processed, and it wasn't matched, clear out the processedby fields. Otherwise, assume the other person is still editing it financialTransaction.ProcessedByPersonAliasId = null; financialTransaction.ProcessedDateTime = null; rockContext.SaveChanges(); } }
/// <summary> /// Handles the Delete event of the gTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param> protected void gTransactions_Delete( object sender, Rock.Web.UI.Controls.RowEventArgs e ) { var rockContext = new RockContext(); FinancialTransactionService service = new FinancialTransactionService( rockContext ); FinancialTransaction item = service.Get( e.RowKeyId ); if ( item != null ) { string errorMessage; if ( !service.CanDelete( item, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } service.Delete( item ); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Handles the Delete event of the gTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param> protected void gTransactions_Delete( object sender, Rock.Web.UI.Controls.RowEventArgs e ) { var rockContext = new RockContext(); var transactionService = new FinancialTransactionService( rockContext ); var transaction = transactionService.Get( e.RowKeyId ); if ( transaction != null ) { string errorMessage; if ( !transactionService.CanDelete( transaction, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } // prevent deleting a Transaction that is in closed batch if (transaction.Batch != null ) { if ( transaction.Batch.Status == BatchStatus.Closed ) { mdGridWarning.Show( string.Format( "This {0} is assigned to a closed {1}", FinancialTransaction.FriendlyTypeName, FinancialBatch.FriendlyTypeName ), ModalAlertType.Information ); return; } } if ( transaction.BatchId.HasValue ) { string caption = ( transaction.AuthorizedPersonAlias != null && transaction.AuthorizedPersonAlias.Person != null ) ? transaction.AuthorizedPersonAlias.Person.FullName : string.Format( "Transaction: {0}", transaction.Id ); HistoryService.SaveChanges( rockContext, typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), transaction.BatchId.Value, new List<string> { "Deleted transaction" }, caption, typeof( FinancialTransaction ), transaction.Id, false ); } transactionService.Delete( transaction ); rockContext.SaveChanges(); RockPage.UpdateBlocks( "~/Blocks/Finance/BatchDetail.ascx" ); } BindGrid(); }
/// <summary> /// Handles the Click event of the btnSaveFinancialTransaction 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 lbSaveTransaction_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var financialTransactionService = new Rock.Model.FinancialTransactionService( rockContext ); Rock.Model.FinancialTransaction financialTransaction = null; int financialTransactionId = !string.IsNullOrEmpty( hfIdTransValue.Value ) ? int.Parse( hfIdTransValue.Value ) : 0; // null if not associated with a batch int? batchId = hfBatchId.Value.AsInteger(); if ( financialTransactionId == 0 ) { financialTransaction = new Rock.Model.FinancialTransaction(); financialTransactionService.Add( financialTransaction ); financialTransaction.BatchId = batchId; } else { financialTransaction = financialTransactionService.Get( financialTransactionId ); } if ( ppAuthorizedPerson.PersonId != null ) { financialTransaction.AuthorizedPersonId = ppAuthorizedPerson.PersonId; } else { financialTransaction.AuthorizedPersonId = null; } if ( ddlCurrencyType.SelectedItem.ToString() == "Credit Card" ) { financialTransaction.CreditCardTypeValueId = int.Parse( ddlCreditCardType.SelectedValue ); } else { financialTransaction.CreditCardTypeValueId = null; } financialTransaction.CurrencyTypeValueId = int.Parse( ddlCurrencyType.SelectedValue ); if ( !string.IsNullOrEmpty( ddlPaymentGateway.SelectedValue ) ) { var gatewayEntity = Rock.Web.Cache.EntityTypeCache.Read( new Guid( ddlPaymentGateway.SelectedValue ) ); if ( gatewayEntity != null ) { financialTransaction.GatewayEntityTypeId = gatewayEntity.Id; } } financialTransaction.SourceTypeValueId = int.Parse( ddlSourceType.SelectedValue ); financialTransaction.TransactionTypeValueId = int.Parse( ddlTransactionType.SelectedValue ); financialTransaction.Summary = tbSummary.Text; financialTransaction.TransactionCode = tbTransactionCode.Text; financialTransaction.TransactionDateTime = dtTransactionDateTime.SelectedDateTime; rockContext.SaveChanges(); if ( batchId != null ) { Dictionary<string, string> qryString = new Dictionary<string, string>(); qryString["financialBatchid"] = hfBatchId.Value; NavigateToParentPage( qryString ); } else { NavigateToParentPage(); } }