Пример #1
0
        /// <summary>
        /// Binds the contributions grid.
        /// </summary>
        protected void BindContributionsGrid()
        {
            // Hide the whole Amount column if the block setting is set to hide
            var showAmount = GetAttributeValue("ShowAmount").AsBoolean();
            var amountCol  = gContributions.ColumnsOfType <RockLiteralField>()
                             .FirstOrDefault(c => c.ID == "lTransactionDetailAmount");

            if (amountCol != null)
            {
                amountCol.Visible = showAmount;
            }

            var rockContext             = new RockContext();
            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();
            int groupMemberId           = hfGroupMemberId.Value.AsInteger();

            var financialTransactionQry = new FinancialTransactionService(rockContext).Queryable();

            financialTransactionQry = financialTransactionQry.Where(a =>
                                                                    a.TransactionDetails.Any(d => d.EntityTypeId == entityTypeIdGroupMember && d.EntityId == groupMemberId));

            financialTransactionQry = financialTransactionQry.OrderByDescending(a => a.TransactionDateTime);

            gContributions.SetLinqDataSource(financialTransactionQry);
            gContributions.DataBind();
        }
Пример #2
0
        /// <summary>
        /// Handles the GridRebind event of the gTransactionDetails control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void gTransactionDetails_GridRebind(object sender, EventArgs e)
        {
            FinancialTransaction transaction = new FinancialTransaction();

            transaction = new FinancialTransactionService(new RockContext()).Get(hfIdTransValue.ValueAsInt());
            BindTransactionDetailGrid(transaction);
        }
        /// <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 Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var rockContext = (RockContext)serviceInstance.Context;

            string[] selectionValues = selection.Split('|');
            if (selectionValues.Length < 3)
            {
                return(null);
            }

            DateTime?startDate     = selectionValues[0].AsDateTime();
            DateTime?endDate       = selectionValues[1].AsDateTime();
            var      accountGuids  = selectionValues[2].Split(',').Select(a => a.AsGuid()).ToList();
            var      accountIdList = new FinancialAccountService((RockContext)serviceInstance.Context).GetByGuids(accountGuids).Select(a => a.Id).ToList();

            int transactionTypeContributionId = Rock.Web.Cache.DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()).Id;

            var financialTransactionsQry = new FinancialTransactionService(rockContext).Queryable()
                                           .Where(xx => xx.TransactionTypeValueId == transactionTypeContributionId);

            if (accountIdList.Any())
            {
                if (accountIdList.Count == 1)
                {
                    int accountId = accountIdList.First();
                    financialTransactionsQry = financialTransactionsQry.Where(xx => xx.TransactionDetails.Any(a => a.AccountId == accountId));
                }
                else
                {
                    financialTransactionsQry = financialTransactionsQry.Where(xx => xx.TransactionDetails.Any(a => accountIdList.Contains(a.AccountId)));
                }
            }

            var firstContributionDateQry = financialTransactionsQry
                                           .GroupBy(xx => xx.AuthorizedPersonAlias.PersonId)
                                           .Select(ss => new
            {
                PersonId = ss.Key,
                FirstTransactionSundayDate = ss.Min(a => a.SundayDate)
            });

            if (startDate.HasValue)
            {
                firstContributionDateQry = firstContributionDateQry.Where(xx => xx.FirstTransactionSundayDate >= startDate.Value);
            }

            if (endDate.HasValue)
            {
                firstContributionDateQry = firstContributionDateQry.Where(xx => xx.FirstTransactionSundayDate < endDate);
            }

            var innerQry = firstContributionDateQry.Select(xx => xx.PersonId).AsQueryable();

            var qry = new PersonService(rockContext).Queryable()
                      .Where(p => innerQry.Any(xx => xx == p.Id));

            Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.Person>(qry, parameterExpression, "p");

            return(extractedFilterExpression);
        }
Пример #4
0
        /// <summary>
        /// Shows the message if stale.
        /// </summary>
        private void ShowMessageIfStale()
        {
            /* 2021-09-30 MDP
             *
             * Rules for when giving characteristics are considered stale
             *
             * Show the ‘stale’ message when the last gift was over { TypicalFrequency + 2* Frequency Standard Deviation }   days.
             *
             * Message should be worded as:
             *
             * The giving characteristics below were generated (stale time) ago at the time of the last gift.
             * Information on bin, percentile and typical gift patterns represent values from that time period.
             *
             */

            nbGivingCharacteristicsStaleWarning.Visible = false;
            var lastTransaction   = new FinancialTransactionService(new RockContext()).GetGivingAutomationSourceTransactionQueryByGivingId(Person.GivingId).Max(a => ( DateTime? )a.TransactionDateTime);
            var frequencyMeanDays = Person.GetAttributeValue(Rock.SystemGuid.Attribute.PERSON_GIVING_FREQUENCY_MEAN_DAYS.AsGuid()).AsDecimalOrNull();
            var frequencyStandardDeviationDays = Person.GetAttributeValue(Rock.SystemGuid.Attribute.PERSON_GIVING_FREQUENCY_STD_DEV_DAYS.AsGuid()).AsDecimalOrNull();

            if (lastTransaction.HasValue && frequencyMeanDays.HasValue && frequencyStandardDeviationDays.HasValue)
            {
                var consideredStaleAfterDays = frequencyMeanDays.Value + (frequencyStandardDeviationDays.Value * 2);
                var timeSpanSinceLastUpdated = RockDateTime.Now - lastTransaction.Value;
                if (( decimal )timeSpanSinceLastUpdated.TotalDays > consideredStaleAfterDays)
                {
                    nbGivingCharacteristicsStaleWarning.Text    = $@"The giving characteristics below were generated {lastTransaction.ToElapsedString().ToLower()} at the time of the last gift. Information on bin, percentile and typical gift patterns represent values from that time period.";
                    nbGivingCharacteristicsStaleWarning.Visible = true;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Handles the Click event of the lbEdit 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 lbEdit_Click(object sender, EventArgs e)
        {
            BindDropdowns();
            var transaction = new FinancialTransactionService(new RockContext()).Get(hfIdTransValue.ValueAsInt());

            ShowEdit(transaction);
        }
        /// <summary>
        /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set.
        /// </summary>
        /// <param name="entityType">The type of entity in the result set.</param>
        /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param>
        /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param>
        /// <param name="selection">A formatted string representing the filter settings.</param>
        /// <returns>
        /// A Linq Expression that can be used to filter an IQueryable.
        /// </returns>
        /// <exception cref="System.Exception">Filter issue(s):  + errorMessages.AsDelimited( ;  )</exception>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var settings = new FilterSettings(selection);

            var context = (RockContext)serviceInstance.Context;

            // Get the Financial Transaction Data View.
            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.DataViewGuid, context);

            // Evaluate the Data View that defines the Person's Financial Transaction.
            var financialTransactionService = new FinancialTransactionService(context);

            var financialTransactionQuery = financialTransactionService.Queryable();

            if (dataView != null)
            {
                financialTransactionQuery = DataComponentSettingsHelper.FilterByDataView(financialTransactionQuery, dataView, financialTransactionService);
            }

            var transactionPersonsKey = financialTransactionQuery.Select(a => a.AuthorizedPersonAliasId);
            // Get all of the Person corresponding to the qualifying Financial Transactions.
            var qry = new PersonService(context).Queryable()
                      .Where(g => g.Aliases.Any(k => transactionPersonsKey.Contains(k.Id)));

            // Retrieve the Filter Expression.
            var extractedFilterExpression = FilterExpressionExtractor.Extract <Model.Person>(qry, parameterExpression, "g");

            return(extractedFilterExpression);
        }
        public FinancialTransactionsExport Export(
            int page      = 1,
            int pageSize  = 1000,
            string sortBy = null,
            System.Web.UI.WebControls.SortDirection sortDirection = System.Web.UI.WebControls.SortDirection.Ascending,
            int?dataViewId         = null,
            DateTime?modifiedSince = null,
            DateTime?startDateTime = null,
            DateTime?endDateTime   = null,
            string attributeKeys   = null,
            AttributeReturnType attributeReturnType = AttributeReturnType.Raw
            )
        {
            // limit to 'API Max Items Per Page' global attribute
            int maxPageSize    = GlobalAttributesCache.Get().GetValue("core_ExportAPIsMaxItemsPerPage").AsIntegerOrNull() ?? 1000;
            var actualPageSize = Math.Min(pageSize, maxPageSize);

            FinancialTransactionExportOptions exportOptions = new FinancialTransactionExportOptions
            {
                SortBy              = sortBy,
                SortDirection       = sortDirection,
                DataViewId          = dataViewId,
                ModifiedSince       = modifiedSince,
                AttributeList       = AttributesExport.GetAttributesFromAttributeKeys <FinancialTransaction>(attributeKeys),
                AttributeReturnType = attributeReturnType,
                StartDateTime       = startDateTime,
                EndDateTime         = endDateTime
            };

            var rockContext = new RockContext();
            var financialTransactionService = new FinancialTransactionService(rockContext);

            return(financialTransactionService.GetFinancialTransactionExport(page, actualPageSize, exportOptions));
        }
        /// <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();
        }
Пример #9
0
        /// <summary>
        /// Binds the yearly summary.
        /// </summary>
        private void BindYearlySummary()
        {
            var givingId = Person.GivingId;

            using (var rockContext = new RockContext())
            {
                DateTime?startDate;
                if (!IsYearlySummaryExpanded)
                {
                    // Only show this current year and last year
                    startDate = RockDateTime.Now.StartOfYear().AddYears(-1);
                }
                else
                {
                    startDate = null;
                }

                var monthlyAccountGivingHistoryList = new FinancialTransactionService(rockContext).GetGivingAutomationMonthlyAccountGivingHistory(givingId, startDate);

                var financialAccounts = new FinancialAccountService(rockContext).Queryable()
                                        .AsNoTracking()
                                        .ToDictionary(k => k.Id, v => v.Name);

                var summaryList = monthlyAccountGivingHistoryList
                                  .GroupBy(a => new { a.Year, a.AccountId })
                                  .Select(t => new SummaryRecord
                {
                    Year        = t.Key.Year,
                    AccountId   = t.Key.AccountId,
                    TotalAmount = t.Sum(d => d.Amount)
                })
                                  .OrderByDescending(a => a.Year)
                                  .ToList();

                var contributionSummaries = new List <ContributionSummary>();
                foreach (var item in summaryList.GroupBy(a => a.Year))
                {
                    var contributionSummary = new ContributionSummary();
                    contributionSummary.Year           = item.Key;
                    contributionSummary.SummaryRecords = new List <SummaryRecord>();
                    foreach (var a in item)
                    {
                        a.AccountName = financialAccounts.ContainsKey(a.AccountId) ? financialAccounts[a.AccountId] : string.Empty;
                        contributionSummary.SummaryRecords.Add(a);
                    }

                    contributionSummary.TotalAmount = item.Sum(a => a.TotalAmount);
                    contributionSummaries.Add(contributionSummary);
                }

                rptYearSummary.DataSource = contributionSummaries;
                rptYearSummary.DataBind();

                // Show the correct button to expand or collapse
                lbShowLessYearlySummary.Visible = IsYearlySummaryExpanded;
                lbShowMoreYearlySummary.Visible = !IsYearlySummaryExpanded;
            }
        }
Пример #10
0
        private void BindData()
        {
            RockContext rockContext = new RockContext();

            dvpRefundReason.DefinedTypeId = DefinedTypeCache.Get(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON.AsGuid(), rockContext).Id;

            if (!ddlSystemCommunication.SelectedValueAsInt().HasValue)
            {
                SystemCommunicationService systemCommunicationService = new SystemCommunicationService(rockContext);
                var systemCommunications = systemCommunicationService.Queryable().Where(c => c.IsActive == true).Select(e => new { Title = e.Category.Name + " - " + e.Title, e.Id }).OrderBy(e => e.Title).ToList();
                systemCommunications.Insert(0, new { Title = "", Id = 0 });
                ddlSystemCommunication.DataSource     = systemCommunications;
                ddlSystemCommunication.DataValueField = "Id";
                ddlSystemCommunication.DataTextField  = "Title";
                ddlSystemCommunication.DataBind();
            }

            List <int> registrationTemplateIds = rtpRegistrationTemplate.ItemIds.AsIntegerList();

            registrationTemplateIds.RemoveAll(i => i.Equals(0));
            int     itemCount     = 0;
            decimal totalPayments = 0;

            if (liRegistration.Visible == true && registrationTemplateIds.Count > 0)
            {
                RegistrationTemplateService registrationTemplateService = new RegistrationTemplateService(rockContext);
                var templates = registrationTemplateService.GetByIds(rtpRegistrationTemplate.ItemIds.AsIntegerList());
                var instances = templates.SelectMany(t => t.Instances);
                if (ddlRegistrationInstance.SelectedValueAsId().HasValue&& ddlRegistrationInstance.SelectedValueAsId() > 0)
                {
                    var instanceId = ddlRegistrationInstance.SelectedValueAsId();
                    instances = instances.Where(i => i.Id == instanceId);
                }
                itemCount     = instances.SelectMany(i => i.Registrations).Count();
                totalPayments = instances.SelectMany(i => i.Registrations).ToList().SelectMany(r => r.Payments).Sum(p => p.Transaction.TotalAmount);

                if (!ddlRegistrationInstance.SelectedValueAsInt().HasValue)
                {
                    var instanceList = templates.SelectMany(t => t.Instances).OrderBy(i => i.Name).Select(i => new { i.Id, i.Name }).ToList();
                    instanceList.Insert(0, new { Id = 0, Name = "" });
                    ddlRegistrationInstance.DataSource     = instanceList;
                    ddlRegistrationInstance.DataValueField = "Id";
                    ddlRegistrationInstance.DataTextField  = "Name";
                    ddlRegistrationInstance.DataBind();
                }
            }

            if (liTransactionCodes.Visible == true && tbTransactionCodes.Text.Length > 0)
            {
                var codes = tbTransactionCodes.Text.SplitDelimitedValues();
                FinancialTransactionService financialTransactionService = new FinancialTransactionService(rockContext);
                var transactions = financialTransactionService.Queryable().Where(ft => codes.Contains(ft.TransactionCode));
                totalPayments = transactions.SelectMany(t => t.TransactionDetails).Sum(td => td.Amount);
                itemCount     = transactions.Count();
            }
            lAlert.Text = itemCount + (pnlRegistration.Visible?" Registrations - ": " Transactions - ") + totalPayments.FormatAsCurrency() + " Total";
        }
Пример #11
0
        private void BindGrid()
        {
            TransactionSearchValue searchValue = GetSearchValue();

            var transactionService = new FinancialTransactionService();

            grdTransactions.DataSource = transactionService.Get(searchValue).ToList();
            grdTransactions.DataBind();
        }
Пример #12
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            var totalAmountQuery = new FinancialTransactionService(context).Queryable()
                                   .Select(p => p.TransactionDetails.Sum(a => a.Amount));

            var selectTotalAmountExpression = SelectExpressionExtractor.Extract(totalAmountQuery, entityIdProperty, "p");

            return(selectTotalAmountExpression);
        }
        /// <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 Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var rockContext = (RockContext)serviceInstance.Context;

            SelectionConfig selectionConfig = SelectionConfig.Parse(selection);

            if (selectionConfig == null)
            {
                return(null);
            }

            DateRange dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(selectionConfig.DelimitedValues);

            int transactionTypeContributionId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()).Id;
            var financialTransactionsQry      = new FinancialTransactionService(rockContext)
                                                .Queryable()
                                                .Where(xx => xx.TransactionTypeValueId == transactionTypeContributionId);

            var accountIdList = new FinancialAccountService(( RockContext )serviceInstance.Context).GetByGuids(selectionConfig.AccountGuids).Select(a => a.Id).ToList();

            if (accountIdList.Any())
            {
                if (accountIdList.Count == 1)
                {
                    int accountId = accountIdList.First();
                    financialTransactionsQry = financialTransactionsQry.Where(xx => xx.TransactionDetails.Any(a => a.AccountId == accountId));
                }
                else
                {
                    financialTransactionsQry = financialTransactionsQry.Where(xx => xx.TransactionDetails.Any(a => accountIdList.Contains(a.AccountId)));
                }
            }

            var firstContributionDateQry = financialTransactionsQry
                                           .GroupBy(xx => xx.AuthorizedPersonAlias.PersonId)
                                           .Select(ss => new
            {
                PersonId             = ss.Key,
                FirstTransactionDate = ss.Min(a => selectionConfig.UseSundayDate == true ? a.SundayDate : a.TransactionDateTime)
            });

            if (dateRange.Start.HasValue)
            {
                firstContributionDateQry = firstContributionDateQry.Where(xx => xx.FirstTransactionDate >= dateRange.Start.Value);
            }

            if (dateRange.End.HasValue)
            {
                firstContributionDateQry = firstContributionDateQry.Where(xx => xx.FirstTransactionDate < dateRange.End.Value);
            }

            var innerQry = firstContributionDateQry.Select(xx => xx.PersonId).AsQueryable();
            var qry      = new PersonService(rockContext).Queryable().Where(p => innerQry.Any(xx => xx == p.Id));

            return(FilterExpressionExtractor.Extract <Rock.Model.Person>(qry, parameterExpression, "p"));
        }
Пример #14
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);
                    }
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Gets the transaction.
        /// </summary>
        /// <param name="transactionId">The transaction identifier.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        private FinancialTransaction GetTransaction(int transactionId, RockContext rockContext = null)
        {
            rockContext = rockContext ?? new RockContext();
            var txn = new FinancialTransactionService(rockContext)
                      .Queryable("AuthorizedPersonAlias.Person,TransactionTypeValue,SourceTypeValue,GatewayEntityType,CurrencyTypeValue,TransactionDetails,ScheduledTransaction,ProcessedByPersonAlias.Person")
                      .Where(t => t.Id == transactionId)
                      .FirstOrDefault();

            return(txn);
        }
Пример #16
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="itemKey">The item key.</param>
        /// <param name="itemKeyValue">The item key value.</param>
        public void ShowDetail(string itemKey, int itemKeyValue)
        {
            if (!itemKey.Equals("transactionId") && !!itemKey.Equals("batchfk"))
            {
                return;
            }

            FinancialTransaction transaction = null;

            if (!itemKeyValue.Equals(0))
            {
                transaction = new FinancialTransactionService(new RockContext()).Get(itemKeyValue);
            }
            else
            {
                transaction = new FinancialTransaction {
                    Id = 0
                };
            }

            hfIdTransValue.Value = transaction.Id.ToString();
            hfBatchId.Value      = PageParameter("financialBatchId");

            if (!readOnly)
            {
                lbEdit.Visible = true;
                if (transaction.Id > 0)
                {
                    ShowSummary(transaction);
                }
                else
                {
                    BindDropdowns();
                    ShowEdit(transaction);
                }

                gTransactionDetails.Actions.ShowAdd = true;
                gTransactionDetails.IsDeleteEnabled = true;
                pnlImageUpload.Visible = true;
            }
            else
            {
                lbEdit.Visible = false;
                ShowSummary(transaction);
                gTransactionDetails.Actions.ShowAdd = false;
                gTransactionDetails.IsDeleteEnabled = false;
                pnlImageUpload.Visible = false;
            }

            lbSave.Visible = !readOnly;
            LoadAccountDropDown();
            BindTransactionDetailGrid(transaction);
            BindDefinedTypeDropdown(ddlTransactionImageType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_IMAGE_TYPE), "Transaction Image Type");
            LoadRelatedImages(transaction.Id);
        }
Пример #17
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();
        }
Пример #18
0
        /// <summary>
        /// Handles the Click event of the 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 btnPrint_Click(object sender, EventArgs e)
        {
            var keys              = new List <int>();
            var mergeFields       = Rock.Lava.LavaHelper.GetCommonMergeFields(RockPage);
            var rockContext       = new RockContext();
            var formattedTemplate = GetAttributeValue("FormattedTemplate");

            if (gPayments.SelectedKeys.Count > 0)
            {
                keys = gPayments.SelectedKeys.Cast <int>().ToList();
            }
            else
            {
                gPayments.AllowPaging = false;
                BindPaymentsGrid();
                gPayments.AllowPaging = true;

                foreach (DataKey k in gPayments.DataKeys)
                {
                    keys.Add(( int )k.Value);
                }
            }

            int instanceId = PageParameter("RegistrationInstanceId").AsInteger();

            mergeFields.Add("RegistrationInstance", new RegistrationInstanceService(rockContext).Get(instanceId));

            var transactions = new FinancialTransactionService(rockContext)
                               .Queryable()
                               .Where(t => keys.Contains(t.Id))
                               .OrderBy(t => t.TransactionDateTime)
                               .ToList();

            mergeFields.Add("Transactions", transactions);

            var currencyTypes = transactions
                                .GroupBy(t => t.FinancialPaymentDetail.CurrencyAndCreditCardType)
                                .Select(g => new {
                Title  = g.Key,
                Amount = g.Sum(t => t.TotalAmount)
            })
                                .ToList();

            mergeFields.Add("CurrencyTypes", currencyTypes);

            mergeFields.Add("Total", transactions.Sum(t => t.TotalAmount));

            ltFormattedOutput.Text = formattedTemplate.ResolveMergeFields(mergeFields);

            pnlDetails.Visible = false;
            pnlPrint.Visible   = true;
        }
Пример #19
0
        /// <summary>
        /// Issue a refund for the transaction
        /// </summary>
        /// <param name="transaction">The transaction to refund.</param>
        /// <param name="label">The label for the log entry (Registration or Transaction).</param>
        /// <param name="value">The value for the log entry for this line item.</param>
        /// <returns></returns>
        private bool issueRefund(FinancialTransaction transaction, string label, string value)
        {
            decimal refundAmount = transaction.TotalAmount + transaction.Refunds.Sum(r => r.FinancialTransaction.TotalAmount);

            // If refunds totalling the amount of the payments have not already been issued
            if (transaction.TotalAmount > 0 && refundAmount > 0)
            {
                string errorMessage;

                using (var refundRockContext = new RockContext())
                {
                    var financialTransactionService = new FinancialTransactionService(refundRockContext);
                    var refundTransaction           = financialTransactionService.ProcessRefund(transaction, refundAmount, dvpRefundReason.SelectedDefinedValueId, tbRefundSummary.Text, true, string.Empty, out errorMessage);

                    if (refundTransaction != null)
                    {
                        refundRockContext.SaveChanges();
                    }

                    if (!string.IsNullOrWhiteSpace(errorMessage))
                    {
                        results["Fail"] += string.Format("Failed refund for {0} {1}: {2}",
                                                         label,
                                                         value,
                                                         errorMessage) + Environment.NewLine;
                    }
                    else
                    {
                        results["Success"] += string.Format("Successfully issued {0} refund for {1} {2} payment {3} ({4}) - Refund Transaction Id: {5}, Amount: {6}",

                                                            refundAmount < transaction.TotalAmount ? "partial" : "full",
                                                            label,
                                                            value,
                                                            transaction.TransactionCode,
                                                            transaction.TotalAmount,
                                                            refundTransaction.TransactionCode,
                                                            refundTransaction.TotalAmount.FormatAsCurrency()) + Environment.NewLine;
                        return(true);
                    }
                }
            }
            else if (transaction.Refunds.Count > 0)
            {
                results["Success"] += string.Format("Refund already issued for {0} {1} payment {2} ({3})",
                                                    label,
                                                    value,
                                                    transaction.TransactionCode,
                                                    transaction.TotalAmount) + Environment.NewLine;
            }
            return(false);
        }
Пример #20
0
        public void FinancialTransactionDateKeyJoinsCorrectly()
        {
            var expectedRecordCount = 15;
            var transactionYear     = 2015;
            var settledYear         = 2016;

            using (var rockContext = new RockContext())
            {
                var financialTransactionService = new FinancialTransactionService(rockContext);

                var minTransactionDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, transactionYear);
                var maxTransactionDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, transactionYear);

                var minSettledDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, settledYear);
                var maxSettledDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, settledYear);



                for (var i = 0; i < 15; i++)
                {
                    var financialTransaction = BuildFinancialTransaction(rockContext,
                                                                         TestDataHelper.GetRandomDateInRange(minTransactionDateValue, maxTransactionDateValue),
                                                                         TestDataHelper.GetRandomDateInRange(minSettledDateValue, maxSettledDateValue));

                    financialTransactionService.Add(financialTransaction);
                }

                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var financialTransactionService = new FinancialTransactionService(rockContext);

                var financialTransactions = financialTransactionService.
                                            Queryable().
                                            Where(i => i.ForeignKey == financialTransactionForeignKey).
                                            Where(i => i.TransactionSourceDate.CalendarYear == transactionYear);

                Assert.AreEqual(expectedRecordCount, financialTransactions.Count());
                Assert.IsNotNull(financialTransactions.First().TransactionSourceDate);

                financialTransactions = financialTransactionService.
                                        Queryable().
                                        Where(i => i.ForeignKey == financialTransactionForeignKey).
                                        Where(i => i.SettledSourceDate.CalendarYear == settledYear);

                Assert.AreEqual(expectedRecordCount, financialTransactions.Count());
                Assert.IsNotNull(financialTransactions.First().SettledSourceDate);
            }
        }
Пример #21
0
        /// <summary>
        /// Process a refund for a transaction.
        /// </summary>
        /// <param name="transaction">The refund transaction.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="reasonValueId">The reason value identifier.</param>
        /// <param name="summary">The summary.</param>
        /// <param name="process">if set to <c>true</c> [process].</param>
        /// <param name="batchNameSuffix">The batch name suffix.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        public static FinancialTransaction ProcessRefund(this FinancialTransaction transaction, decimal?amount, int?reasonValueId, string summary, bool process, string batchNameSuffix, out string errorMessage)
        {
            using (var rockContext = new RockContext())
            {
                var service           = new FinancialTransactionService(rockContext);
                var refundTransaction = service.ProcessRefund(transaction, amount, reasonValueId, summary, process, batchNameSuffix, out errorMessage);

                if (refundTransaction != null)
                {
                    rockContext.SaveChanges();
                }

                return(refundTransaction);
            }
        }
Пример #22
0
        /// <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 Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var values = selection.Split('|');

            ComparisonType comparisonType = values[0].ConvertToEnum <ComparisonType>(ComparisonType.EqualTo);
            decimal?       amountValue    = values[1].AsDecimalOrNull();

            var qry = new FinancialTransactionService((RockContext)serviceInstance.Context).Queryable();
            var totalAmountEqualQuery = qry.Where(p => p.TransactionDetails.Sum(a => a.Amount) == amountValue);

            BinaryExpression compareEqualExpression = FilterExpressionExtractor.Extract <Rock.Model.FinancialTransaction>(totalAmountEqualQuery, parameterExpression, "p") as BinaryExpression;
            BinaryExpression result = FilterExpressionExtractor.AlterComparisonType(comparisonType, compareEqualExpression, null);

            return(result);
        }
Пример #23
0
        /// <summary>
        /// Handles the Delete event of the gBatchList 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 gBatchList_Delete(object sender, RowEventArgs e)
        {
            var rockContext        = new RockContext();
            var batchService       = new FinancialBatchService(rockContext);
            var transactionService = new FinancialTransactionService(rockContext);
            var batch = batchService.Get(e.RowKeyId);

            if (batch != null)
            {
                if (batch.IsAuthorized(Rock.Security.Authorization.DELETE, CurrentPerson))
                {
                    string errorMessage;
                    if (!batchService.CanDelete(batch, out errorMessage))
                    {
                        mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                        return;
                    }

                    rockContext.WrapTransaction(() =>
                    {
                        foreach (var txn in transactionService.Queryable()
                                 .Where(t => t.BatchId == batch.Id))
                        {
                            transactionService.Delete(txn);
                        }

                        var changes = new History.HistoryChangeList();
                        changes.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Batch");
                        HistoryService.SaveChanges(
                            rockContext,
                            typeof(FinancialBatch),
                            Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                            batch.Id,
                            changes);

                        batchService.Delete(batch);

                        rockContext.SaveChanges();
                    });
                }
                else
                {
                    mdGridWarning.Show("You are not authorized to delete the selected batch.", ModalAlertType.Warning);
                }
            }

            BindGrid();
        }
Пример #24
0
        /// <summary>
        /// Gets the financial transactions query.
        /// </summary>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        private IQueryable <FinancialTransaction> GetFinancialTransactionQuery(AchievementTypeCache achievementTypeCache, RockContext rockContext = null)
        {
            if (null == rockContext)
            {
                rockContext = new RockContext();
            }

            var includeChildAccounts = GetAttributeValue(achievementTypeCache, AttributeKey.IncludeChildFinancialAccounts).AsBoolean();
            var attributeMinDate     = GetAttributeValue(achievementTypeCache, AttributeKey.StartDateTime).AsDateTime();
            var attributeMaxDate     = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime();

            // Get the account identifier for this achievement type
            var accountId = GetFinancialAccountId(achievementTypeCache, rockContext);

            if (!accountId.HasValue)
            {
                return(null);
            }

            // For the include child accounts option to work we need to get the descendents for this Type
            var accountService       = new FinancialAccountService(rockContext);
            var accountDescendentIds = includeChildAccounts ? accountService.GetAllDescendentIds(accountId.Value).ToList() : new List <int>();

            var transactionService = new FinancialTransactionService(rockContext);

            var query = transactionService.Queryable()
                        .AsNoTracking()
                        .Where(t =>
                               t.AuthorizedPersonAliasId.HasValue &&
                               t.RefundDetails == null &&
                               t.TransactionDetails.Any(a =>
                                                        a.Amount > 0 &&
                                                        (a.AccountId == accountId ||
                                                         accountDescendentIds.Contains(a.AccountId))));

            if (attributeMinDate.HasValue)
            {
                query = query.Where(t => t.TransactionDateTime >= attributeMinDate.Value);
            }

            if (attributeMaxDate.HasValue)
            {
                var dayAfterMaxDate = attributeMaxDate.Value.AddDays(1);
                query = query.Where(t => t.TransactionDateTime < dayAfterMaxDate);
            }

            return(query);
        }
Пример #25
0
        /// <summary>
        /// Gets the warnings.
        /// </summary>
        /// <returns></returns>
        private List <string> GetWarnings(FinancialBatch batch)
        {
            var warningList = new List <string>();

            if (batch.Status == BatchStatus.Open)
            {
                var transactionService = new FinancialTransactionService(new RockContext());
                var transactionList    = transactionService.Queryable().Where(trans => trans.BatchId == batch.Id && trans.AuthorizedPersonId == null).ToList();
                if (transactionList.Count > 0)
                {
                    warningList.Add("UNTIED");
                }
            }

            return(warningList);
        }
Пример #26
0
        /// <summary>
        /// Binds the contributions grid.
        /// </summary>
        protected void BindContributionsGrid()
        {
            var rockContext             = new RockContext();
            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();
            int groupMemberId           = hfGroupMemberId.Value.AsInteger();

            var financialTransactionQry = new FinancialTransactionService(rockContext).Queryable();

            financialTransactionQry = financialTransactionQry.Where(a =>
                                                                    a.TransactionDetails.Any(d => d.EntityTypeId == entityTypeIdGroupMember && d.EntityId == groupMemberId));

            financialTransactionQry = financialTransactionQry.OrderByDescending(a => a.TransactionDateTime);

            gContributions.SetLinqDataSource(financialTransactionQry);
            gContributions.DataBind();
        }
Пример #27
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();
            }
        }
        public static void ClassInitialize(TestContext testContext)
        {
            _rockContext              = new RockContext();
            _accountService           = new FinancialAccountService(_rockContext);
            _batchService             = new FinancialBatchService(_rockContext);
            _transactionService       = new FinancialTransactionService(_rockContext);
            _paymentService           = new FinancialPaymentDetailService(_rockContext);
            _achievementTypeService   = new AchievementTypeService(_rockContext);
            _definedValueService      = new DefinedValueService(_rockContext);
            _definedTypeService       = new DefinedTypeService(_rockContext);
            _transactionDetailService = new FinancialTransactionDetailService(_rockContext);

            DeleteTestData();
            PopulateDefinedValues();
            CreateFinancialTransactionData();
            CreateAchievementTypeData();
        }
Пример #29
0
        /// <summary>
        /// Publishes the gift event.
        /// </summary>
        /// <param name="transactionId">The transaction identifier.</param>
        /// <param name="eventType">Type of the event.</param>
        /// <param name="gatewaySupportedCardTypesDefinedValueGuid">[Optional] The <see cref="Guid"/> of the <see cref="DefinedValue"/> that indicates the credit card types supported by the <see cref="FinancialGateway"/> for a specified currency.</param>
        /// <param name="gatewayCurrencyUnitMultiple">[Optional] The <see cref="Guid"/> of the <see cref="DefinedValue"/> that indicates the "unit multiple" (e.g., 100 for dollars) of the currency specified by the gatway.</param>
        public static void PublishTransactionEvent(int transactionId, string eventType = null, Guid?gatewaySupportedCardTypesDefinedValueGuid = null, Guid?gatewayCurrencyUnitMultiple = null)
        {
            using (var rockContext = new RockContext())
            {
                var transactionService = new FinancialTransactionService(rockContext);
                var gateway            = transactionService.Queryable()
                                         .AsNoTracking()
                                         .Include(t => t.FinancialGateway)
                                         .Where(t => t.Id == transactionId)
                                         .Select(t => t.FinancialGateway)
                                         .FirstOrDefault();

                var gatewayComponent     = gateway?.GetGatewayComponent();
                var searchKeyTiedGateway = gatewayComponent as ISearchKeyTiedGateway;
                var searchKeyTypeGuid    = searchKeyTiedGateway?.GetPersonSearchKeyTypeGuid(gateway);
                var data = GetGiftWasGivenMessageData(rockContext, transactionId, searchKeyTypeGuid, gatewaySupportedCardTypesDefinedValueGuid, gatewayCurrencyUnitMultiple);

                if (data != null)
                {
                    var statusGateway = gatewayComponent as IStatusProvidingGateway;

                    if (eventType.IsNullOrWhiteSpace())
                    {
                        eventType =
                            statusGateway.IsPendingStatus(data.FinancialTransaction.Status) ? GiftEventTypes.GiftPending :
                            statusGateway.IsSuccessStatus(data.FinancialTransaction.Status) ? GiftEventTypes.GiftSuccess :
                            statusGateway.IsFailureStatus(data.FinancialTransaction.Status) ? GiftEventTypes.GiftFailure :
                            null;
                    }

                    if (!eventType.IsNullOrWhiteSpace())
                    {
                        var message = new GiftWasGivenMessage
                        {
                            EventType            = eventType,
                            Address              = data.Address,
                            FinancialTransaction = data.FinancialTransaction,
                            Person = data.Person,
                            Time   = RockDateTime.Now
                        };

                        _ = RockMessageBus.PublishAsync <GivingEventQueue, GiftWasGivenMessage>(message);
                    }
                }
            }
        }
Пример #30
0
        /// <summary>
        /// Create a new payment processor to handle a single automated payment.
        /// </summary>
        /// <param name="currentPersonAliasId">The current user's person alias ID. Possibly the REST user.</param>
        /// <param name="automatedPaymentArgs">The arguments describing how to charge the payment and store the resulting transaction</param>
        /// <param name="rockContext">The context to use for loading and saving entities</param>
        /// <param name="enableDuplicateChecking">If false, the payment will be charged even if there is a similar transaction for the same person
        /// within a short time period.</param>
        /// <param name="enableScheduleAdherenceProtection">If false and a schedule is indicated in the args, the payment will be charged even if
        /// the schedule has already been processed according to it's frequency.</param>
        public AutomatedPaymentProcessor(int?currentPersonAliasId, AutomatedPaymentArgs automatedPaymentArgs, RockContext rockContext, bool enableDuplicateChecking = true, bool enableScheduleAdherenceProtection = true)
        {
            _rockContext                       = rockContext;
            _automatedPaymentArgs              = automatedPaymentArgs;
            _currentPersonAliasId              = currentPersonAliasId;
            _enableDuplicateChecking           = enableDuplicateChecking;
            _enableScheduleAdherenceProtection = enableScheduleAdherenceProtection;
            _futureTransaction                 = null;

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

            _payment = null;
        }