/// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            TransactionSearchValue searchValue  = GetSearchValue();
            SortProperty           sortProperty = rGridTransactions.SortProperty;

            var transactionService = new FinancialTransactionService();
            var queryable          = transactionService.Get(searchValue);

            if (_batch != null)
            {
                queryable = queryable.Where(t => t.BatchId.HasValue && t.BatchId.Value == _batch.Id);
            }

            if (_person != null)
            {
                queryable = queryable.Where(t => t.AuthorizedPersonId == _person.Id);
            }

            if (sortProperty != null)
            {
                queryable = queryable.Sort(sortProperty);
            }
            else
            {
                queryable = queryable.OrderBy(t => t.TransactionDateTime);
            }

            rGridTransactions.DataSource = queryable.ToList();
            rGridTransactions.DataBind();
        }
Пример #2
0
        private void BindGrid()
        {
            TransactionSearchValue searchValue = GetSearchValue();

            var transactionService = new FinancialTransactionService();

            grdTransactions.DataSource = transactionService.Get(searchValue).ToList();
            grdTransactions.DataBind();
        }
Пример #3
0
        /// <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 = new Dictionary <string, object>();
                        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("Amounts", accountAmounts);

                        var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(person);
                        globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value));

                        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);
                    }
                }
            }
        }
Пример #4
0
        /// <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();
        }
Пример #5
0
        /// <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();
            }
        }
Пример #6
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            TransactionSearchValue searchValue  = GetSearchValue();
            SortProperty           sortProperty = rGridTransactions.SortProperty;

            var transactionService = new FinancialTransactionService();
            var queryable          = transactionService.Get(searchValue);

            if (sortProperty != null)
            {
                queryable = queryable.Sort(sortProperty);
            }
            else
            {
                queryable = queryable.OrderBy(t => t.TransactionDateTime);
            }

            rGridTransactions.DataSource = queryable.ToList();
            rGridTransactions.DataBind();
        }
Пример #7
0
        /// <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();
        }
Пример #8
0
        /// <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();
        }
Пример #9
0
        /// <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("ForeignKey", transaction.ForeignKey);
                        mergeFields.Add("Transaction", transaction);
                        mergeFields.Add("Amounts", accountAmounts);

                        var transactionDetailEntityList = transaction.TransactionDetails.Where(a => a.EntityTypeId.HasValue && a.EntityId.HasValue).ToList();
                        var transactionEntityList       = new List <IEntity>();
                        foreach (var transactionDetailEntity in transactionDetailEntityList)
                        {
                            var transactionEntityType = EntityTypeCache.Get(transactionDetailEntity.EntityTypeId.Value);
                            if (transactionEntityType != null)
                            {
                                var      dbContext       = Reflection.GetDbContextForEntityType(transactionEntityType.GetEntityType());
                                IService serviceInstance = Reflection.GetServiceForEntityType(transactionEntityType.GetEntityType(), dbContext);
                                if (serviceInstance != null)
                                {
                                    System.Reflection.MethodInfo getMethod = serviceInstance.GetType().GetMethod("Get", new Type[] { typeof(int) });
                                    var transactionEntity = getMethod.Invoke(serviceInstance, new object[] { transactionDetailEntity.EntityId.Value }) as Rock.Data.IEntity;
                                    transactionEntityList.Add(transactionEntity);
                                }
                            }
                        }

                        if (transactionEntityList.Any())
                        {
                            mergeFields.Add("TransactionEntityList", transactionEntityList);
                            mergeFields.Add("TransactionEntity", transactionEntityList.First());
                        }

                        var emailMessage = new RockEmailMessage(SystemEmailGuid);
                        emailMessage.AddRecipient(new RockEmailMessageRecipient(person, mergeFields));
                        var errors = new List <string>();
                        // errors will be logged by send
                        emailMessage.Send(out errors);
                    }
                }
            }
        }
Пример #10
0
        /// <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();

            rockContext.WrapTransaction(() =>
            {
                if (contextEntity is Person)
                {
                    var personService = new PersonService(rockContext);
                    var changes       = new History.HistoryChangeList();
                    var _person       = personService.Get(contextEntity.Id);

                    History.EvaluateChange(changes, "Foreign Key", _person.ForeignKey, tbForeignKey.Text);
                    _person.ForeignKey = tbForeignKey.Text;

                    History.EvaluateChange(changes, "Foreign Guid", _person.ForeignGuid.ToString(), tbForeignGuid.Text);
                    _person.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();

                    History.EvaluateChange(changes, "Foreign Id", _person.ForeignId.ToString(), tbForeignId.Text);
                    _person.ForeignId = tbForeignId.Text.AsType <int?>();

                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(Person),
                                Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                _person.Id,
                                changes);
                        }
                    }
                }
                else if (contextEntity is FinancialAccount)
                {
                    var accountService = new FinancialAccountService(rockContext);
                    var _account       = accountService.Get(contextEntity.Id);

                    _account.ForeignKey  = tbForeignKey.Text;
                    _account.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _account.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is FinancialBatch)
                {
                    var batchService = new FinancialBatchService(rockContext);
                    var changes      = new History.HistoryChangeList();
                    var _batch       = batchService.Get(contextEntity.Id);

                    History.EvaluateChange(changes, "Foreign Key", _batch.ForeignKey, tbForeignKey.Text);
                    _batch.ForeignKey = tbForeignKey.Text;

                    History.EvaluateChange(changes, "Foreign Guid", _batch.ForeignGuid.ToString(), tbForeignGuid.Text);
                    _batch.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();

                    History.EvaluateChange(changes, "Foreign Id", _batch.ForeignId.ToString(), tbForeignId.Text);
                    _batch.ForeignId = tbForeignId.Text.AsType <int?>();

                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(FinancialBatch),
                                Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                _batch.Id,
                                changes);
                        }
                    }
                }
                else if (contextEntity is FinancialPledge)
                {
                    var pledgeService = new FinancialPledgeService(rockContext);
                    var _pledge       = pledgeService.Get(contextEntity.Id);

                    _pledge.ForeignKey  = tbForeignKey.Text;
                    _pledge.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _pledge.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is FinancialTransaction)
                {
                    var transactionService = new FinancialTransactionService(rockContext);
                    var changes            = new History.HistoryChangeList();
                    var _transaction       = transactionService.Get(contextEntity.Id);

                    History.EvaluateChange(changes, "Foreign Key", _transaction.ForeignKey, tbForeignKey.Text);
                    _transaction.ForeignKey = tbForeignKey.Text;

                    History.EvaluateChange(changes, "Foreign Guid", _transaction.ForeignGuid.ToString(), tbForeignGuid.Text);
                    _transaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();

                    History.EvaluateChange(changes, "Foreign Id", _transaction.ForeignId.ToString(), tbForeignId.Text);
                    _transaction.ForeignId = tbForeignId.Text.AsType <int?>();

                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(FinancialTransaction),
                                Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(),
                                _transaction.Id,
                                changes);
                        }
                    }
                }
                else if (contextEntity is FinancialScheduledTransaction)
                {
                    var transactionScheduledService = new FinancialScheduledTransactionService(rockContext);
                    var _scheduledTransaction       = transactionScheduledService.Get(contextEntity.Id);

                    _scheduledTransaction.ForeignKey  = tbForeignKey.Text;
                    _scheduledTransaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _scheduledTransaction.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is Group)
                {
                    var groupService = new GroupService(rockContext);
                    var _group       = groupService.Get(contextEntity.Id);

                    _group.ForeignKey  = tbForeignKey.Text;
                    _group.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _group.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is GroupMember)
                {
                    var groupMemberService = new GroupMemberService(rockContext);
                    var changes            = new History.HistoryChangeList();
                    var _groupMember       = groupMemberService.Get(contextEntity.Id);

                    History.EvaluateChange(changes, "Foreign Key", _groupMember.ForeignKey, tbForeignKey.Text);
                    _groupMember.ForeignKey = tbForeignKey.Text;

                    History.EvaluateChange(changes, "Foreign Guid", _groupMember.ForeignGuid.ToString(), tbForeignGuid.Text);
                    _groupMember.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();

                    History.EvaluateChange(changes, "Foreign Id", _groupMember.ForeignId.ToString(), tbForeignId.Text);
                    _groupMember.ForeignId = tbForeignId.Text.AsType <int?>();

                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(GroupMember),
                                Rock.SystemGuid.Category.HISTORY_PERSON_GROUP_MEMBERSHIP.AsGuid(),
                                _groupMember.Id,
                                changes);
                        }
                    }
                }
                else if (contextEntity is Metric)
                {
                    var metricService = new MetricService(rockContext);
                    var _metric       = metricService.Get(contextEntity.Id);

                    _metric.ForeignKey  = tbForeignKey.Text;
                    _metric.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _metric.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is Location)
                {
                    var locationService = new LocationService(rockContext);
                    var _location       = locationService.Get(contextEntity.Id);

                    _location.ForeignKey  = tbForeignKey.Text;
                    _location.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _location.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is PrayerRequest)
                {
                    var prayerRequestService = new PrayerRequestService(rockContext);
                    var _request             = prayerRequestService.Get(contextEntity.Id);

                    _request.ForeignKey  = tbForeignKey.Text;
                    _request.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _request.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is ContentChannel)
                {
                    var contentChannelService = new ContentChannelService(rockContext);
                    var _channel = contentChannelService.Get(contextEntity.Id);

                    _channel.ForeignKey  = tbForeignKey.Text;
                    _channel.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _channel.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
                else if (contextEntity is ContentChannelItem)
                {
                    var contentChannelItemService = new ContentChannelItemService(rockContext);
                    var _item = contentChannelItemService.Get(contextEntity.Id);

                    _item.ForeignKey  = tbForeignKey.Text;
                    _item.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>();
                    _item.ForeignId   = tbForeignId.Text.AsType <int?>();

                    rockContext.SaveChanges();
                }
            });

            Page.Response.Redirect(Page.Request.Url.ToString(), true);
        }
Пример #11
0
        /// <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);
            }
        }