/// <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(); }
/// <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); }
/// <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; } } }
/// <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(); }
/// <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; } }
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"; }
private void BindGrid() { TransactionSearchValue searchValue = GetSearchValue(); var transactionService = new FinancialTransactionService(); grdTransactions.DataSource = transactionService.Get(searchValue).ToList(); grdTransactions.DataBind(); }
/// <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")); }
/// <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); } } } }
/// <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); }
/// <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); }
/// <summary> /// Handles the Delete event of the gTransactions control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs" /> instance containing the event data.</param> protected void gTransactions_Delete(object sender, Rock.Web.UI.Controls.RowEventArgs e) { var rockContext = new RockContext(); var transactionService = new FinancialTransactionService(rockContext); var transaction = transactionService.Get(e.RowKeyId); if (transaction != null) { string errorMessage; if (!transactionService.CanDelete(transaction, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } // prevent deleting a Transaction that is in closed batch if (transaction.Batch != null) { if (transaction.Batch.Status == BatchStatus.Closed) { mdGridWarning.Show(string.Format("This {0} is assigned to a closed {1}", FinancialTransaction.FriendlyTypeName, FinancialBatch.FriendlyTypeName), ModalAlertType.Information); return; } } if (transaction.BatchId.HasValue) { string caption = (transaction.AuthorizedPersonAlias != null && transaction.AuthorizedPersonAlias.Person != null) ? transaction.AuthorizedPersonAlias.Person.FullName : string.Format("Transaction: {0}", transaction.Id); HistoryService.SaveChanges( rockContext, typeof(FinancialBatch), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), transaction.BatchId.Value, new List <string> { "Deleted transaction" }, caption, typeof(FinancialTransaction), transaction.Id, false ); } transactionService.Delete(transaction); rockContext.SaveChanges(); RockPage.UpdateBlocks("~/Blocks/Finance/BatchDetail.ascx"); } BindGrid(); }
/// <summary> /// Handles the Click event of the 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; }
/// <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); }
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); } }
/// <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); } }
/// <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); }
/// <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(); }
/// <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); }
/// <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); }
/// <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(); }
/// <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(); }
/// <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); } } } }
/// <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; }