private IQueryable <FinancialAccount> GetAccounts() { var accountService = new FinancialAccountService(); SortProperty sortProperty = rGridAccount.SortProperty; var accountQuery = accountService.Queryable(); string accountNameFilter = rAccountFilter.GetUserPreference("Account Name"); if (!string.IsNullOrEmpty(accountNameFilter)) { accountQuery = accountQuery.Where(account => account.Name.Contains(accountNameFilter)); } string activeFilter = rAccountFilter.GetUserPreference("Active"); if (!string.IsNullOrWhiteSpace(activeFilter)) { accountQuery = accountQuery.Where(account => account.IsActive == (activeFilter == "Yes")); } string taxDeductibleFilter = rAccountFilter.GetUserPreference("Tax Deductible"); if (!string.IsNullOrWhiteSpace(taxDeductibleFilter)) { accountQuery = accountQuery.Where(account => account.IsTaxDeductible == (taxDeductibleFilter == "Yes")); } accountQuery = accountQuery.OrderBy(a => a.Order); return(accountQuery); }
/// <summary> /// Binds the filter. /// </summary> private void BindFilter() { nreAmount.DelimitedValues = gfSettings.GetUserPreference("Amount"); ddlFrequency.BindToDefinedType(DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY.AsGuid())); ddlFrequency.Items.Insert(0, new ListItem(string.Empty, string.Empty)); string freqPreference = gfSettings.GetUserPreference("Frequency"); if (!string.IsNullOrWhiteSpace(freqPreference)) { ddlFrequency.SetValue(freqPreference); } drpDates.DelimitedValues = gfSettings.GetUserPreference("Created"); var accountService = new FinancialAccountService(new RockContext()); var accounts = accountService .Queryable().AsNoTracking() .Where(a => a.IsActive); ddlAccount.Visible = string.IsNullOrWhiteSpace(GetAttributeValue("Accounts")); ddlAccount.Items.Add(new ListItem(string.Empty, string.Empty)); foreach (FinancialAccount account in accounts.OrderBy(a => a.Order)) { ListItem li = new ListItem(account.Name, account.Id.ToString()); li.Selected = account.Id.ToString() == gfSettings.GetUserPreference("Account"); ddlAccount.Items.Add(li); } cbIncludeInactive.Checked = !string.IsNullOrWhiteSpace(gfSettings.GetUserPreference("Include Inactive")); }
/// <summary> /// Binds the filter. /// </summary> private void BindFilter() { //DateTime fromDate; //if ( !DateTime.TryParse( rFilter.GetUserPreference( "From Date" ), out fromDate ) ) //{ // fromDate = DateTime.Today; //} //dtStartDate.Text = fromDate.ToShortDateString(); dtStartDate.Text = rFilter.GetUserPreference("From Date"); dtEndDate.Text = rFilter.GetUserPreference("To Date"); txtFromAmount.Text = rFilter.GetUserPreference("From Amount"); txtToAmount.Text = rFilter.GetUserPreference("To Amount"); txtTransactionCode.Text = rFilter.GetUserPreference("Transaction Code"); var accountService = new FinancialAccountService(); foreach (FinancialAccount account in accountService.Queryable()) { ListItem li = new ListItem(account.Name, account.Id.ToString()); li.Selected = account.Id.ToString() == rFilter.GetUserPreference("Account"); ddlAccount.Items.Add(li); } ddlAccount.Items.Insert(0, Rock.Constants.All.ListItem); BindDefinedTypeDropdown(ddlTransactionType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_TYPE), "Transaction Type"); BindDefinedTypeDropdown(ddlCurrencyType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE), "Currency Type"); BindDefinedTypeDropdown(ddlCreditCardType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE), "Credit Card Type"); BindDefinedTypeDropdown(ddlSourceType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_SOURCE_TYPE), "Source"); }
/// <summary> /// Binds the Account list grid. /// </summary> private void BindGrid() { FinancialAccount contextAccount = ContextEntity <FinancialAccount>(); if (contextAccount == null) { var accountService = new FinancialAccountService(); SortProperty sortProperty = rGridAccount.SortProperty; var accountQuery = accountService.Queryable(); if (!string.IsNullOrEmpty(txtAccountName.Text)) { accountQuery = accountQuery.Where(account => account.Name.Contains(txtAccountName.Text)); } if (dtStartDate.SelectedDate != null) { accountQuery = accountQuery.Where(account => account.StartDate >= dtStartDate.SelectedDate); } if (dtEndDate.SelectedDate != null) { accountQuery = accountQuery.Where(account => account.EndDate <= dtEndDate.SelectedDate); } if (ddlIsActive.SelectedValue != "Any") { accountQuery = accountQuery.Where(account => account.IsActive == (ddlIsActive.SelectedValue == "Active")); } if (ddlIsTaxDeductible.SelectedValue != "Any") { accountQuery = accountQuery.Where(account => account.IsTaxDeductible == (ddlIsTaxDeductible.SelectedValue == "Yes")); } if (sortProperty != null) { rGridAccount.DataSource = accountQuery.Sort(sortProperty).ToList(); } else { rGridAccount.DataSource = accountQuery.OrderBy(f => f.Name).ToList(); } } else { rGridAccount.DataSource = contextAccount; } rGridAccount.DataBind(); }
/// <summary> /// Gets the accounts. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private IQueryable <FinancialAccount> GetAccounts(RockContext rockContext) { var accountService = new FinancialAccountService(rockContext); SortProperty sortProperty = rGridAccount.SortProperty; var accountQuery = accountService.Queryable(); string accountNameFilter = rAccountFilter.GetUserPreference("Account Name"); if (!string.IsNullOrEmpty(accountNameFilter)) { accountQuery = accountQuery.Where(account => account.Name.Contains(accountNameFilter)); } int campusId = int.MinValue; if (int.TryParse(rAccountFilter.GetUserPreference("Campus"), out campusId)) { accountQuery = accountQuery.Where(account => account.Campus.Id == campusId); } string publicFilter = rAccountFilter.GetUserPreference("Public"); if (!string.IsNullOrWhiteSpace(publicFilter)) { accountQuery = accountQuery.Where(account => (account.IsPublic ?? false) == (publicFilter == "Yes")); } string activeFilter = rAccountFilter.GetUserPreference("Active"); if (!string.IsNullOrWhiteSpace(activeFilter)) { accountQuery = accountQuery.Where(account => account.IsActive == (activeFilter == "Yes")); } string taxDeductibleFilter = rAccountFilter.GetUserPreference("Tax Deductible"); if (!string.IsNullOrWhiteSpace(taxDeductibleFilter)) { accountQuery = accountQuery.Where(account => account.IsTaxDeductible == (taxDeductibleFilter == "Yes")); } accountQuery = accountQuery.OrderBy(a => a.Order); return(accountQuery); }
/// <summary> /// Binds the filter. /// </summary> private void BindFilter() { drpDates.DelimitedValues = rFilter.GetUserPreference("Date Range"); nreAmount.DelimitedValues = rFilter.GetUserPreference("Amount Range"); txtTransactionCode.Text = rFilter.GetUserPreference("Transaction Code"); var accountService = new FinancialAccountService(); ddlAccount.Items.Add(new ListItem(string.Empty, string.Empty)); foreach (FinancialAccount account in accountService.Queryable()) { ListItem li = new ListItem(account.Name, account.Id.ToString()); li.Selected = account.Id.ToString() == rFilter.GetUserPreference("Account"); ddlAccount.Items.Add(li); } BindDefinedTypeDropdown(ddlTransactionType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_TYPE), "Transaction Type"); BindDefinedTypeDropdown(ddlCurrencyType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE), "Currency Type"); BindDefinedTypeDropdown(ddlCreditCardType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE), "Credit Card Type"); BindDefinedTypeDropdown(ddlSourceType, new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_SOURCE_TYPE), "Source Type"); }
/// <summary> /// Loads the accounts. /// </summary> private void LoadAccounts() { var rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); List <Guid> selectedAccounts = new List <Guid>(); if (!string.IsNullOrWhiteSpace(GetAttributeValue("Accounts"))) { selectedAccounts = GetAttributeValue("Accounts").Split(',').AsGuidList(); } var accountList = accountService.Queryable() .Where(a => selectedAccounts.Contains(a.Guid)) .OrderBy(a => a.Order) .Select(a => new { a.Id, a.PublicName }).ToList(); if (accountList.Any()) { foreach (var account in accountList) { ListItem checkbox = new ListItem(account.PublicName, account.Id.ToString(), true); checkbox.Selected = true; cblAccounts.Items.Add(checkbox); } } else { cblAccounts.Items.Clear(); } // only show Account Checkbox list if there are accounts are configured for the block cblAccounts.Visible = accountList.Any(); }
private void LoadAccounts() { var rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); List <Guid> selectedAccounts = new List <Guid>();; if (!string.IsNullOrWhiteSpace(GetAttributeValue("Accounts"))) { selectedAccounts = GetAttributeValue("Accounts").Split(',').Select(Guid.Parse).ToList(); } var accounts = accountService.Queryable() .Where(a => selectedAccounts.Contains(a.Guid)) .OrderBy(a => a.Order); foreach (var account in accounts.ToList()) { ListItem checkbox = new ListItem(account.PublicName, account.Id.ToString(), true); checkbox.Selected = true; cblAccounts.Items.Add(checkbox); } }
/// <summary> /// Adds any registration instances given in the XML file. /// </summary> /// <param name="elemRegistrationInstances"></param> /// <param name="rockContext"></param> private void AddRegistrationInstances( XElement elemRegistrationInstances, RockContext rockContext ) { if ( elemRegistrationInstances == null ) { return; } foreach ( var element in elemRegistrationInstances.Elements( "registrationInstance" ) ) { // skip any illegally formatted items if ( element.Attribute( "templateGuid" ) == null ) { continue; } // Now find the matching registration template RegistrationInstanceService registrationInstanceService = new RegistrationInstanceService( rockContext ); RegistrationTemplateService registrationTemplateService = new RegistrationTemplateService( rockContext ); Guid templateGuid = element.Attribute( "templateGuid" ).Value.AsGuid(); var registrationTemplate = registrationTemplateService.Queryable() .Where( g => g.Guid == templateGuid ) .FirstOrDefault(); if ( registrationTemplate == null ) { throw new NotSupportedException( string.Format( "unknown registration template: {0}", templateGuid ) ); } // Merge lava fields // LAVA additionalReminderDetails Dictionary<string, object> mergeObjects = new Dictionary<string, object>(); DateTime? registrationStartsDate = null; DateTime? registrationEndsDate = null; DateTime? sendReminderDate = null; var additionalReminderDetails = string.Empty; var additionalConfirmationDetails = string.Empty; if ( element.Attribute( "registrationStarts" ) != null ) { var y = element.Attribute( "registrationStarts" ).Value.ResolveMergeFields( mergeObjects ); registrationStartsDate = DateTime.Parse( y ); } if ( element.Attribute( "registrationEnds" ) != null ) { registrationEndsDate = DateTime.Parse( element.Attribute( "registrationEnds" ).Value.ResolveMergeFields( mergeObjects ) ); } if ( element.Attribute( "sendReminderDate" ) != null ) { sendReminderDate = DateTime.Parse( element.Attribute( "sendReminderDate" ).Value.ResolveMergeFields( mergeObjects ) ); } if ( element.Attribute( "additionalReminderDetails" ) != null ) { additionalReminderDetails = element.Attribute( "additionalReminderDetails" ).Value; additionalReminderDetails = additionalReminderDetails.ResolveMergeFields( mergeObjects ); } if ( element.Attribute( "additionalConfirmationDetails" ) != null ) { additionalConfirmationDetails = element.Attribute( "additionalConfirmationDetails" ).Value; additionalConfirmationDetails = additionalConfirmationDetails.ResolveMergeFields( mergeObjects ); } // Get the contact info int? contactPersonAliasId = null; if ( element.Attribute( "contactPersonGuid" ) != null ) { var guid = element.Attribute( "contactPersonGuid" ).Value.AsGuid(); if ( _peopleAliasDictionary.ContainsKey( guid ) ) { contactPersonAliasId = _peopleAliasDictionary[element.Attribute( "contactPersonGuid" ).Value.AsGuid()]; } } // Find the matching account FinancialAccountService financialGatewayService = new FinancialAccountService( rockContext ); string accountName = element.Attribute( "account" ) != null ? element.Attribute( "account" ).Value : string.Empty; var account = financialGatewayService.Queryable() .Where( g => g.Name == accountName ) .FirstOrDefault(); RegistrationInstance registrationInstance = new RegistrationInstance() { Guid = ( element.Attribute( "guid" ) != null ) ? element.Attribute( "guid" ).Value.Trim().AsGuid() : Guid.NewGuid(), Name = ( element.Attribute( "name" ) != null ) ? element.Attribute( "name" ).Value.Trim() : "New " + registrationTemplate.Name, IsActive = true, RegistrationTemplateId = registrationTemplate.Id, StartDateTime = registrationStartsDate, EndDateTime = registrationEndsDate, MaxAttendees = element.Attribute( "maxAttendees" ) != null ? element.Attribute( "maxAttendees" ).Value.AsInteger() : 0, SendReminderDateTime = sendReminderDate, ContactPersonAliasId = contactPersonAliasId, ContactPhone = element.Attribute( "contactPhone" ) != null ? element.Attribute( "contactPhone" ).Value : string.Empty, ContactEmail = element.Attribute( "contactEmail" ) != null ? element.Attribute( "contactEmail" ).Value : string.Empty, AccountId = ( account != null ) ? (int?)account.Id : null, AdditionalReminderDetails = HttpUtility.HtmlDecode( additionalReminderDetails ), AdditionalConfirmationDetails = HttpUtility.HtmlDecode( additionalConfirmationDetails ), CreatedDateTime = RockDateTime.Now, ModifiedDateTime = RockDateTime.Now, }; registrationInstanceService.Add( registrationInstance ); } }
/// <summary> /// Processes the payments. /// </summary> /// <param name="gateway">The gateway.</param> /// <param name="batchNamePrefix">The batch name prefix.</param> /// <param name="payments">The payments.</param> /// <param name="batchUrlFormat">The batch URL format.</param> /// <returns></returns> public static string ProcessPayments( FinancialGateway gateway, string batchNamePrefix, List<Payment> payments, string batchUrlFormat = "" ) { int totalPayments = 0; int totalAlreadyDownloaded = 0; int totalNoScheduledTransaction = 0; int totalAdded = 0; var batches = new List<FinancialBatch>(); var batchSummary = new Dictionary<Guid, List<Payment>>(); var initialControlAmounts = new Dictionary<Guid, decimal>(); var allBatchChanges = new Dictionary<Guid, List<string>>(); var allTxnChanges = new Dictionary<Guid, List<string>>(); var txnPersonNames = new Dictionary<Guid, string>(); using ( var rockContext = new RockContext() ) { var accountService = new FinancialAccountService( rockContext ); var txnService = new FinancialTransactionService( rockContext ); var batchService = new FinancialBatchService( rockContext ); var scheduledTxnService = new FinancialScheduledTransactionService( rockContext ); var contributionTxnType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid() ); var defaultAccount = accountService.Queryable() .Where( a => a.IsActive && !a.ParentAccountId.HasValue && ( !a.StartDate.HasValue || a.StartDate.Value <= RockDateTime.Now ) && ( !a.EndDate.HasValue || a.EndDate.Value >= RockDateTime.Now ) ) .OrderBy( a => a.Order ) .FirstOrDefault(); var batchTxnChanges = new Dictionary<Guid, List<string>>(); var batchBatchChanges = new Dictionary<Guid, List<string>>(); foreach ( var payment in payments.Where( p => p.Amount > 0.0M ) ) { totalPayments++; // Only consider transactions that have not already been added if ( txnService.GetByTransactionCode( payment.TransactionCode ) == null ) { var scheduledTransaction = scheduledTxnService.GetByScheduleId( payment.GatewayScheduleId ); if ( scheduledTransaction != null ) { scheduledTransaction.IsActive = payment.ScheduleActive; var txnChanges = new List<string>(); var transaction = new FinancialTransaction(); transaction.FinancialPaymentDetail = new FinancialPaymentDetail(); transaction.Guid = Guid.NewGuid(); allTxnChanges.Add( transaction.Guid, txnChanges ); txnChanges.Add( "Created Transaction (Downloaded from Gateway)" ); transaction.TransactionCode = payment.TransactionCode; History.EvaluateChange( txnChanges, "Transaction Code", string.Empty, transaction.TransactionCode ); transaction.TransactionDateTime = payment.TransactionDateTime; History.EvaluateChange( txnChanges, "Date/Time", null, transaction.TransactionDateTime ); transaction.ScheduledTransactionId = scheduledTransaction.Id; transaction.AuthorizedPersonAliasId = scheduledTransaction.AuthorizedPersonAliasId; History.EvaluateChange( txnChanges, "Person", string.Empty, scheduledTransaction.AuthorizedPersonAlias.Person.FullName ); txnPersonNames.Add( transaction.Guid, scheduledTransaction.AuthorizedPersonAlias.Person.FullName ); transaction.FinancialGatewayId = gateway.Id; History.EvaluateChange( txnChanges, "Gateway", string.Empty, gateway.Name ); transaction.TransactionTypeValueId = contributionTxnType.Id; History.EvaluateChange( txnChanges, "Type", string.Empty, contributionTxnType.Value ); var currencyTypeValue = payment.CurrencyTypeValue; var creditCardTypevalue = payment.CreditCardTypeValue; if ( scheduledTransaction.FinancialPaymentDetail != null ) { if ( currencyTypeValue == null && scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue ) { currencyTypeValue = DefinedValueCache.Read( scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId.Value ); } if ( creditCardTypevalue == null && scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId.HasValue ) { creditCardTypevalue = DefinedValueCache.Read( scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId.Value ); } transaction.FinancialPaymentDetail.AccountNumberMasked = scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked; transaction.FinancialPaymentDetail.NameOnCardEncrypted = scheduledTransaction.FinancialPaymentDetail.NameOnCardEncrypted; transaction.FinancialPaymentDetail.ExpirationMonthEncrypted = scheduledTransaction.FinancialPaymentDetail.ExpirationMonthEncrypted; transaction.FinancialPaymentDetail.ExpirationYearEncrypted = scheduledTransaction.FinancialPaymentDetail.ExpirationYearEncrypted; } if ( currencyTypeValue != null ) { transaction.FinancialPaymentDetail.CurrencyTypeValueId = currencyTypeValue.Id; History.EvaluateChange( txnChanges, "Currency Type", string.Empty, currencyTypeValue.Value ); } if ( creditCardTypevalue != null ) { transaction.FinancialPaymentDetail.CreditCardTypeValueId = creditCardTypevalue.Id; History.EvaluateChange( txnChanges, "Credit Card Type", string.Empty, creditCardTypevalue.Value ); } //transaction.SourceTypeValueId = DefinedValueCache.Read( sourceGuid ).Id; // Try to allocate the amount of the transaction based on the current scheduled transaction accounts decimal remainingAmount = payment.Amount; foreach ( var detail in scheduledTransaction.ScheduledTransactionDetails.Where( d => d.Amount != 0.0M ) ) { var transactionDetail = new FinancialTransactionDetail(); transactionDetail.AccountId = detail.AccountId; if ( detail.Amount <= remainingAmount ) { // If the configured amount for this account is less than or equal to the remaining // amount, allocate the configured amount transactionDetail.Amount = detail.Amount; remainingAmount -= detail.Amount; } else { // If the configured amount is greater than the remaining amount, only allocate // the remaining amount transaction.Summary = "Note: Downloaded transaction amount was less than the configured allocation amounts for the Scheduled Transaction."; detail.Amount = remainingAmount; detail.Summary = "Note: The downloaded amount was not enough to apply the configured amount to this account."; remainingAmount = 0.0M; } transaction.TransactionDetails.Add( transactionDetail ); History.EvaluateChange( txnChanges, detail.Account.Name, 0.0M.ToString( "C2" ), transactionDetail.Amount.ToString( "C2" ) ); History.EvaluateChange( txnChanges, "Summary", string.Empty, transactionDetail.Summary ); if ( remainingAmount <= 0.0M ) { // If there's no amount left, break out of details break; } } // If there's still amount left after allocating based on current config, add the remainder // to the account that was configured for the most amount if ( remainingAmount > 0.0M ) { transaction.Summary = "Note: Downloaded transaction amount was greater than the configured allocation amounts for the Scheduled Transaction."; var transactionDetail = transaction.TransactionDetails .OrderByDescending( d => d.Amount ) .First(); if ( transactionDetail == null && defaultAccount != null ) { transactionDetail = new FinancialTransactionDetail(); transactionDetail.AccountId = defaultAccount.Id; } if ( transactionDetail != null ) { transactionDetail.Amount += remainingAmount; transactionDetail.Summary = "Note: Extra amount was applied to this account."; } History.EvaluateChange( txnChanges, defaultAccount.Name, 0.0M.ToString( "C2" ), transactionDetail.Amount.ToString( "C2" ) ); History.EvaluateChange( txnChanges, "Summary", string.Empty, transactionDetail.Summary ); } // Get the batch var batch = batchService.Get( batchNamePrefix, currencyTypeValue, creditCardTypevalue, transaction.TransactionDateTime.Value, gateway.GetBatchTimeOffset(), batches ); var batchChanges = new List<string>(); if ( batch.Id != 0 ) { initialControlAmounts.AddOrIgnore( batch.Guid, batch.ControlAmount ); } batch.ControlAmount += transaction.TotalAmount; batch.Transactions.Add( transaction ); // Add summary if ( !batchSummary.ContainsKey( batch.Guid ) ) { batchSummary.Add( batch.Guid, new List<Payment>() ); } batchSummary[batch.Guid].Add( payment ); totalAdded++; } else { totalNoScheduledTransaction++; } } else { totalAlreadyDownloaded++; } } foreach ( var batch in batches ) { var batchChanges = new List<string>(); allBatchChanges.Add( batch.Guid, batchChanges ); if ( batch.Id == 0 ) { batchChanges.Add( "Generated the batch" ); History.EvaluateChange( batchChanges, "Batch Name", string.Empty, batch.Name ); History.EvaluateChange( batchChanges, "Status", null, batch.Status ); History.EvaluateChange( batchChanges, "Start Date/Time", null, batch.BatchStartDateTime ); History.EvaluateChange( batchChanges, "End Date/Time", null, batch.BatchEndDateTime ); } if ( initialControlAmounts.ContainsKey( batch.Guid ) ) { History.EvaluateChange( batchChanges, "Control Amount", initialControlAmounts[batch.Guid].ToString( "C2" ), batch.ControlAmount.ToString( "C2" ) ); } } rockContext.WrapTransaction( () => { rockContext.SaveChanges(); foreach ( var batch in batches ) { HistoryService.SaveChanges( rockContext, typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(), batch.Id, allBatchChanges[batch.Guid] ); foreach ( var transaction in batch.Transactions ) { if ( allTxnChanges.ContainsKey( transaction.Guid ) ) { HistoryService.SaveChanges( rockContext, typeof( FinancialBatch ), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), batch.Id, allTxnChanges[transaction.Guid], txnPersonNames[transaction.Guid], typeof( FinancialTransaction ), transaction.Id ); } } } rockContext.SaveChanges(); } ); } StringBuilder sb = new StringBuilder(); sb.AppendFormat( "<li>{0} {1} downloaded.</li>", totalPayments.ToString( "N0" ), ( totalPayments == 1 ? "payment" : "payments" ) ); if ( totalAlreadyDownloaded > 0 ) { sb.AppendFormat( "<li>{0} {1} previously downloaded and {2} already been added.</li>", totalAlreadyDownloaded.ToString( "N0" ), ( totalAlreadyDownloaded == 1 ? "payment was" : "payments were" ), ( totalAlreadyDownloaded == 1 ? "has" : "have" ) ); } if ( totalNoScheduledTransaction > 0 ) { sb.AppendFormat( "<li>{0} {1} could not be matched to an existing scheduled payment profile.</li>", totalNoScheduledTransaction.ToString( "N0" ), ( totalNoScheduledTransaction == 1 ? "payment" : "payments" ) ); } sb.AppendFormat( "<li>{0} {1} successfully added.</li>", totalAdded.ToString( "N0" ), ( totalAdded == 1 ? "payment was" : "payments were" ) ); foreach ( var batchItem in batchSummary ) { int items = batchItem.Value.Count; if (items > 0) { var batch = batches .Where( b => b.Guid.Equals( batchItem.Key ) ) .FirstOrDefault(); string batchName = string.Format("'{0} ({1})'", batch.Name, batch.BatchStartDateTime.Value.ToString("d")); if ( !string.IsNullOrWhiteSpace( batchUrlFormat ) ) { batchName = string.Format( "<a href='{0}'>{1}</a>", string.Format( batchUrlFormat, batch.Id ), batchName ); } decimal sum = batchItem.Value.Select( p => p.Amount ).Sum(); string summaryformat = items == 1 ? "<li>{0} transaction of {1} was added to the {2} batch.</li>" : "<li>{0} transactions totaling {1} were added to the {2} batch</li>"; sb.AppendFormat( summaryformat, items.ToString( "N0" ), sum.ToString( "C2" ), batchName ); } } return sb.ToString(); }
/// <summary> /// Maps the contribution. /// </summary> /// <param name="tableData">The table data.</param> /// <param name="selectedColumns">The selected columns.</param> private void MapContribution( IQueryable<Row> tableData, List<string> selectedColumns = null ) { int transactionEntityTypeId = EntityTypeCache.Read( "Rock.Model.FinancialTransaction" ).Id; var accountService = new FinancialAccountService(); var attributeService = new AttributeService(); var transactionTypeContributionId = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION ) ).Id; int currencyTypeACH = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ) ).Id; int currencyTypeCash = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH ) ).Id; int currencyTypeCheck = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK ) ).Id; int currencyTypeCreditCard = DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ).Id; List<DefinedValue> refundReasons = new DefinedValueService().Queryable().Where( dv => dv.DefinedType.Guid == new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON ) ).ToList(); List<FinancialPledge> pledgeList = new FinancialPledgeService().Queryable().ToList(); List<FinancialAccount> accountList = accountService.Queryable().ToList(); // Add an Attribute for the unique F1 Contribution Id int contributionAttributeId = attributeService.Queryable().Where( a => a.EntityTypeId == transactionEntityTypeId && a.Key == "F1ContributionId" ).Select( a => a.Id ).FirstOrDefault(); if ( contributionAttributeId == 0 ) { var newContributionAttribute = new Rock.Model.Attribute(); newContributionAttribute.Key = "F1ContributionId"; newContributionAttribute.Name = "F1 Contribution Id"; newContributionAttribute.FieldTypeId = IntegerFieldTypeId; newContributionAttribute.EntityTypeId = transactionEntityTypeId; newContributionAttribute.EntityTypeQualifierValue = string.Empty; newContributionAttribute.EntityTypeQualifierColumn = string.Empty; newContributionAttribute.Description = "The FellowshipOne identifier for the contribution that was imported"; newContributionAttribute.DefaultValue = string.Empty; newContributionAttribute.IsMultiValue = false; newContributionAttribute.IsRequired = false; newContributionAttribute.Order = 0; attributeService.Add( newContributionAttribute, ImportPersonAlias ); attributeService.Save( newContributionAttribute, ImportPersonAlias ); contributionAttributeId = newContributionAttribute.Id; } var contributionAttribute = AttributeCache.Read( contributionAttributeId ); // Get all imported contributions var importedContributions = new AttributeValueService().GetByAttributeId( contributionAttributeId ) .Select( av => new { ContributionId = av.Value.AsType<int?>(), TransactionId = av.EntityId } ) .ToDictionary( t => t.ContributionId, t => t.TransactionId ); // List for batching new contributions var newTransactions = new List<FinancialTransaction>(); int completed = 0; int totalRows = tableData.Count(); int percentage = ( totalRows - 1 ) / 100 + 1; ReportProgress( 0, string.Format( "Checking contribution import ({0:N0} found, {1:N0} already exist).", totalRows, importedContributions.Count() ) ); foreach ( var row in tableData ) { int? individualId = row["Individual_ID"] as int?; int? householdId = row["Household_ID"] as int?; int? contributionId = row["ContributionID"] as int?; if ( contributionId != null && !importedContributions.ContainsKey( contributionId ) ) { var transaction = new FinancialTransaction(); transaction.TransactionTypeValueId = transactionTypeContributionId; transaction.AuthorizedPersonId = GetPersonId( individualId, householdId ); transaction.CreatedByPersonAliasId = ImportPersonAlias.Id; transaction.AuthorizedPersonId = GetPersonId( individualId, householdId ); string summary = row["Memo"] as string; if ( summary != null ) { transaction.Summary = summary; } int? batchId = row["BatchID"] as int?; if ( batchId != null && ImportedBatches.Any( b => b.Key == batchId ) ) { transaction.BatchId = ImportedBatches.FirstOrDefault( b => b.Key == batchId ).Value; } DateTime? receivedDate = row["Received_Date"] as DateTime?; if ( receivedDate != null ) { transaction.TransactionDateTime = receivedDate; transaction.CreatedDateTime = receivedDate; } bool isTypeNonCash = false; string contributionType = row["Contribution_Type_Name"] as string; if ( contributionType != null ) { if ( contributionType == "ACH" ) { transaction.CurrencyTypeValueId = currencyTypeACH; } else if ( contributionType == "Cash" ) { transaction.CurrencyTypeValueId = currencyTypeCash; } else if ( contributionType == "Check" ) { transaction.CurrencyTypeValueId = currencyTypeCheck; } else if ( contributionType == "Credit Card" ) { transaction.CurrencyTypeValueId = currencyTypeCreditCard; } else { isTypeNonCash = true; } } string checkNumber = row["Check_Number"] as string; if ( checkNumber != null && checkNumber.AsType<int?>() != null ) { // routing & account set to zero transaction.CheckMicrEncrypted = Encryption.EncryptString( string.Format( "{0}_{1}_{2}", 0, 0, checkNumber ) ); } string fundName = row["Fund_Name"] as string; string subFund = row["Sub_Fund_Name"] as string; decimal? amount = row["Amount"] as decimal?; if ( fundName != null & amount != null ) { FinancialAccount matchingAccount = null; fundName = fundName.Trim(); int? fundCampusId = null; if ( subFund != null ) { subFund = subFund.Trim(); fundCampusId = CampusList.Where( c => c.Name.StartsWith( subFund ) || c.ShortCode == subFund ) .Select( c => (int?)c.Id ).FirstOrDefault(); if ( fundCampusId != null ) { matchingAccount = accountList.FirstOrDefault( a => a.Name.StartsWith( fundName ) && a.CampusId != null && a.CampusId.Equals( fundCampusId ) ); } else { matchingAccount = accountList.FirstOrDefault( a => a.Name.StartsWith( fundName ) && a.Name.StartsWith( subFund ) ); } } else { matchingAccount = accountList.FirstOrDefault( a => a.Name.StartsWith( fundName ) && a.CampusId == null ); } if ( matchingAccount == null ) { matchingAccount = new FinancialAccount(); matchingAccount.Name = fundName; matchingAccount.PublicName = fundName; matchingAccount.IsTaxDeductible = true; matchingAccount.IsActive = true; matchingAccount.CampusId = fundCampusId; matchingAccount.CreatedByPersonAliasId = ImportPersonAlias.Id; accountService.Add( matchingAccount ); accountService.Save( matchingAccount ); accountList.Add( matchingAccount ); } var transactionDetail = new FinancialTransactionDetail(); transactionDetail.Amount = (decimal)amount; transactionDetail.CreatedDateTime = receivedDate; transactionDetail.AccountId = matchingAccount.Id; transactionDetail.IsNonCash = isTypeNonCash; transaction.TransactionDetails.Add( transactionDetail ); if ( amount < 0 ) { var transactionRefund = new FinancialTransactionRefund(); transactionRefund.CreatedDateTime = receivedDate; transactionRefund.RefundReasonSummary = summary; transactionRefund.RefundReasonValueId = refundReasons.Where( dv => summary != null && dv.Name.Contains( summary ) ) .Select( dv => (int?)dv.Id ).FirstOrDefault(); transaction.Refund = transactionRefund; } } // Other Attributes to create: // Pledge_Drive_Name // Stated_Value // True_Value // Liquidation_cost transaction.Attributes = new Dictionary<string, AttributeCache>(); transaction.AttributeValues = new Dictionary<string, List<AttributeValue>>(); transaction.Attributes.Add( contributionAttribute.Key, contributionAttribute ); transaction.AttributeValues.Add( contributionAttribute.Key, new List<AttributeValue>() ); transaction.AttributeValues[contributionAttribute.Key].Add( new AttributeValue() { AttributeId = contributionAttribute.Id, Value = contributionId.ToString(), Order = 0 } ); newTransactions.Add( transaction ); completed++; if ( completed % percentage < 1 ) { int percentComplete = completed / percentage; ReportProgress( percentComplete, string.Format( "{0:N0} contributions imported ({1}% complete).", completed, percentComplete ) ); } else if ( completed % ReportingNumber < 1 ) { RockTransactionScope.WrapTransaction( () => { var transactionService = new FinancialTransactionService(); transactionService.RockContext.FinancialTransactions.AddRange( newTransactions ); transactionService.RockContext.SaveChanges(); var attributeValueService = new AttributeValueService(); foreach ( var contribution in newTransactions.Where( c => c.Attributes.Any() ) ) { var attributeValue = contribution.AttributeValues[contributionAttribute.Key].FirstOrDefault(); if ( attributeValue != null ) { attributeValue.EntityId = contribution.Id; attributeValueService.RockContext.AttributeValues.Add( attributeValue ); } } attributeValueService.RockContext.SaveChanges(); } ); newTransactions.Clear(); ReportPartialProgress(); } } } if ( newTransactions.Any() ) { RockTransactionScope.WrapTransaction( () => { var transactionService = new FinancialTransactionService(); transactionService.RockContext.FinancialTransactions.AddRange( newTransactions ); transactionService.RockContext.SaveChanges(); var attributeValueService = new AttributeValueService(); foreach ( var contribution in newTransactions.Where( c => c.Attributes.Any() ) ) { var attributeValue = contribution.AttributeValues[contributionAttribute.Key].FirstOrDefault(); if ( attributeValue != null ) { attributeValue.EntityId = contribution.Id; attributeValueService.RockContext.AttributeValues.Add( attributeValue ); } } attributeValueService.RockContext.SaveChanges(); } ); } ReportProgress( 100, string.Format( "Finished contribution import: {0:N0} contributions imported.", completed ) ); }
/// <summary> /// Handles the Click event of the btnSave 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 btnSave_Click(object sender, EventArgs e) { if (!Page.IsValid) { return; } var selectedGivingAutomationAccountIds = apGivingAutomationAccounts.SelectedIds; var selectedGivingAutomationAccountGuids = new List <Guid>(); if (selectedGivingAutomationAccountIds.Any()) { using (var rockContext = new RockContext()) { var accountService = new FinancialAccountService(rockContext); selectedGivingAutomationAccountGuids = accountService.Queryable() .AsNoTracking() .Where(a => selectedGivingAutomationAccountIds.Contains(a.Id)) .Select(a => a.Guid) .ToList(); } } var isCustomAccounts = rblAccountTypes.SelectedValue == AccountTypes_Custom; var givingAutomationSettings = GivingAutomationSettings.LoadGivingAutomationSettings(); givingAutomationSettings.FinancialAccountGuids = isCustomAccounts ? selectedGivingAutomationAccountGuids : null; givingAutomationSettings.AreChildAccountsIncluded = isCustomAccounts ? cbGivingAutomationIncludeChildAccounts.Checked : ( bool? )null; givingAutomationSettings.TransactionTypeGuids = cblTransactionTypes.SelectedValues.AsGuidList(); // Main Giving Automation Settings givingAutomationSettings.GivingAutomationJobSettings.IsEnabled = cbEnableGivingAutomation.Checked; givingAutomationSettings.GivingClassificationSettings.RunDays = dwpDaysToUpdateClassifications.SelectedDaysOfWeek?.ToArray(); // Giving Journey Settings givingAutomationSettings.GivingJourneySettings.DaysToUpdateGivingJourneys = dwpDaysToUpdateGivingJourneys.SelectedDaysOfWeek?.ToArray(); givingAutomationSettings.GivingJourneySettings.FormerGiverNoContributionInTheLastDays = nbFormerGiverNoContributionInTheLastDays.IntegerValue; givingAutomationSettings.GivingJourneySettings.FormerGiverMedianFrequencyLessThanDays = nbFormerGiverMedianFrequencyLessThanDays.IntegerValue; givingAutomationSettings.GivingJourneySettings.LapsedGiverNoContributionInTheLastDays = nbLapsedGiverNoContributionInTheLastDays.IntegerValue; givingAutomationSettings.GivingJourneySettings.LapsedGiverMedianFrequencyLessThanDays = nbLapsedGiverMedianFrequencyLessThanDays.IntegerValue; givingAutomationSettings.GivingJourneySettings.NewGiverContributionCountBetweenMinimum = ( int? )nreNewGiverContributionCountBetween.LowerValue; givingAutomationSettings.GivingJourneySettings.NewGiverContributionCountBetweenMaximum = ( int? )nreNewGiverContributionCountBetween.UpperValue; givingAutomationSettings.GivingJourneySettings.NewGiverFirstGiftInTheLastDays = nbNewGiverFirstGiftInLastDays.IntegerValue; givingAutomationSettings.GivingJourneySettings.OccasionalGiverMedianFrequencyDaysMinimum = ( int? )nreOccasionalGiverMedianFrequencyDays.LowerValue; givingAutomationSettings.GivingJourneySettings.OccasionalGiverMedianFrequencyDaysMaximum = ( int? )nreOccasionalGiverMedianFrequencyDays.UpperValue; givingAutomationSettings.GivingJourneySettings.ConsistentGiverMedianLessThanDays = nbConsistentGiverMedianLessThanDays.IntegerValue; // Alerting Settings givingAutomationSettings.GivingAlertingSettings.GlobalRepeatPreventionDurationDays = nbGlobalRepeatPreventionDuration.Text.AsIntegerOrNull(); givingAutomationSettings.GivingAlertingSettings.GratitudeRepeatPreventionDurationDays = nbGratitudeRepeatPreventionDuration.Text.AsIntegerOrNull(); givingAutomationSettings.GivingAlertingSettings.FollowupRepeatPreventionDurationDays = nbFollowupRepeatPreventionDuration.Text.AsIntegerOrNull(); GivingAutomationSettings.SaveGivingAutomationSettings(givingAutomationSettings); this.NavigateToParentPage(); }
/// <summary> /// Maps the pledge. /// </summary> /// <param name="queryable">The queryable.</param> /// <exception cref="System.NotImplementedException"></exception> private void MapPledge( IQueryable<Row> tableData ) { var accountService = new FinancialAccountService(); List<FinancialAccount> importedAccounts = accountService.Queryable().ToList(); List<DefinedValue> pledgeFrequencies = new DefinedValueService().GetByDefinedTypeGuid( new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY ) ).ToList(); List<FinancialPledge> importedPledges = new FinancialPledgeService().Queryable().ToList(); var newPledges = new List<FinancialPledge>(); int completed = 0; int totalRows = tableData.Count(); int percentage = ( totalRows - 1 ) / 100 + 1; ReportProgress( 0, string.Format( "Checking pledge import ({0:N0} found).", totalRows ) ); foreach ( var row in tableData ) { decimal? amount = row["Total_Pledge"] as decimal?; DateTime? startDate = row["Start_Date"] as DateTime?; DateTime? endDate = row["End_Date"] as DateTime?; if ( amount != null && startDate != null && endDate != null ) { int? individualId = row["Individual_ID"] as int?; int? householdId = row["Household_ID"] as int?; int? personId = GetPersonId( individualId, householdId ); if ( personId != null && !importedPledges.Any( p => p.PersonId == personId && p.TotalAmount == amount && p.StartDate.Equals( startDate ) ) ) { var pledge = new FinancialPledge(); pledge.CreatedByPersonAliasId = ImportPersonAlias.Id; pledge.StartDate = (DateTime)startDate; pledge.EndDate = (DateTime)endDate; pledge.TotalAmount = (decimal)amount; string frequency = row["Pledge_Frequency_Name"] as string; if ( frequency != null ) { if ( frequency == "One Time" || frequency == "As Can" ) { pledge.PledgeFrequencyValueId = pledgeFrequencies.FirstOrDefault( f => f.Guid == new Guid( Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME ) ).Id; } else { pledge.PledgeFrequencyValueId = pledgeFrequencies .Where( f => f.Name.StartsWith( frequency ) || f.Description.StartsWith( frequency ) ) .Select( f => f.Id ).FirstOrDefault(); } } string fundName = row["Fund_Name"] as string; string subFund = row["Sub_Fund_Name"] as string; if ( fundName != null ) { FinancialAccount matchingAccount = null; int? fundCampusId = null; if ( subFund != null ) { // match by campus if the subfund appears to be a campus fundCampusId = CampusList.Where( c => c.Name.StartsWith( subFund ) || c.ShortCode == subFund ) .Select( c => (int?)c.Id ).FirstOrDefault(); if ( fundCampusId != null ) { matchingAccount = importedAccounts.FirstOrDefault( a => a.Name.StartsWith( fundName ) && a.CampusId != null && a.CampusId.Equals( fundCampusId ) ); } else { matchingAccount = importedAccounts.FirstOrDefault( a => a.Name.StartsWith( fundName ) && a.Name.StartsWith( subFund ) ); } } else { matchingAccount = importedAccounts.FirstOrDefault( a => a.Name.StartsWith( fundName ) ); } if ( matchingAccount == null ) { matchingAccount = new FinancialAccount(); matchingAccount.Name = fundName; matchingAccount.PublicName = fundName; matchingAccount.IsTaxDeductible = true; matchingAccount.IsActive = true; matchingAccount.CampusId = fundCampusId; matchingAccount.CreatedByPersonAliasId = ImportPersonAlias.Id; accountService.Add( matchingAccount ); accountService.Save( matchingAccount ); importedAccounts.Add( matchingAccount ); pledge.AccountId = matchingAccount.Id; } } // Attributes to add? // Pledge_Drive_Name newPledges.Add( pledge ); completed++; if ( completed % percentage < 1 ) { int percentComplete = completed / percentage; ReportProgress( percentComplete, string.Format( "{0:N0} pledges imported ({1}% complete).", completed, percentComplete ) ); } else if ( completed % ReportingNumber < 1 ) { RockTransactionScope.WrapTransaction( () => { var pledgeService = new FinancialPledgeService(); pledgeService.RockContext.FinancialPledges.AddRange( newPledges ); pledgeService.RockContext.SaveChanges(); } ); ReportPartialProgress(); } } } } if ( newPledges.Any() ) { RockTransactionScope.WrapTransaction( () => { var pledgeService = new FinancialPledgeService(); pledgeService.RockContext.FinancialPledges.AddRange( newPledges ); pledgeService.RockContext.SaveChanges(); } ); } ReportProgress( 100, string.Format( "Finished pledge import: {0:N0} pledges imported.", completed ) ); }
/// <summary> /// Gets the accounts. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private IQueryable<FinancialAccount> GetAccounts( RockContext rockContext ) { var accountService = new FinancialAccountService( rockContext ); SortProperty sortProperty = rGridAccount.SortProperty; var accountQuery = accountService.Queryable(); string accountNameFilter = rAccountFilter.GetUserPreference( "Account Name" ); if ( !string.IsNullOrEmpty( accountNameFilter ) ) { accountQuery = accountQuery.Where( account => account.Name.Contains( accountNameFilter ) ); } int campusId = int.MinValue; if ( int.TryParse( rAccountFilter.GetUserPreference( "Campus" ), out campusId ) ) { accountQuery = accountQuery.Where( account => account.Campus.Id == campusId ); } string publicFilter = rAccountFilter.GetUserPreference( "Public" ); if ( !string.IsNullOrWhiteSpace( publicFilter ) ) { accountQuery = accountQuery.Where( account => ( account.IsPublic ?? false ) == ( publicFilter == "Yes" ) ); } string activeFilter = rAccountFilter.GetUserPreference( "Active" ); if ( !string.IsNullOrWhiteSpace( activeFilter ) ) { accountQuery = accountQuery.Where( account => account.IsActive == ( activeFilter == "Yes" ) ); } string taxDeductibleFilter = rAccountFilter.GetUserPreference( "Tax Deductible" ); if ( !string.IsNullOrWhiteSpace( taxDeductibleFilter ) ) { accountQuery = accountQuery.Where( account => account.IsTaxDeductible == ( taxDeductibleFilter == "Yes" ) ); } accountQuery = accountQuery.OrderBy( a => a.Order ); return accountQuery; }
// checks the settings provided private bool CheckSettings() { nbBlockConfigErrors.Title = string.Empty; nbBlockConfigErrors.Text = string.Empty; // get list of selected accounts filtered by the current campus RockContext rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService( rockContext ); if ( !string.IsNullOrWhiteSpace( GetAttributeValue( "Accounts" ) ) ) { Guid[] selectedAccounts = GetAttributeValue( "Accounts" ).Split( ',' ).Select( s => Guid.Parse( s ) ).ToArray(); ; var accounts = accountService.Queryable() .Where( a => selectedAccounts.Contains( a.Guid ) ); if ( this.CampusId != 0 ) { accounts = accounts.Where( a => a.CampusId.Value == this.CampusId || a.CampusId == null ); } this.Accounts = new Dictionary<int, string>(); foreach ( var account in accounts.OrderBy( a => a.Order ).ToList() ) { this.Accounts.Add( account.Id, account.PublicName ); } } else { nbBlockConfigErrors.Heading = "No Accounts Configured"; nbBlockConfigErrors.Text = "<p>There are currently no accounts configured.</p>"; return false; } // hide cancel buttons if no homepage defined if ( string.IsNullOrWhiteSpace( GetAttributeValue( "Homepage" ) ) ) { lbSearchCancel.Visible = false; lbGivingUnitSelectCancel.Visible = false; lbRegisterCancel.Visible = false; lbAccountEntryCancel.Visible = false; lbSwipeCancel.Visible = false; } // get anonymous person Person anonymousPerson = null; Guid anonymousPersonAliasGuid; if ( Guid.TryParse( GetAttributeValue( "AnonymousPerson" ), out anonymousPersonAliasGuid ) ) { anonymousPerson = new PersonAliasService( rockContext ).Get(anonymousPersonAliasGuid ).Person; } if ( anonymousPerson != null ) { this.AnonymousGiverPersonAliasId = anonymousPerson.PrimaryAliasId; lbGiveAnonymously.Visible = true; } else { lbGiveAnonymously.Visible = false; } _dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() ); if ( _dvcConnectionStatus == null ) { nbBlockConfigErrors.Heading = "Invalid Connection Status"; nbBlockConfigErrors.Text = "<p>The selected Connection Status setting does not exist.</p>"; return false; } _dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() ); if ( _dvcRecordStatus == null ) { nbBlockConfigErrors.Heading = "Invalid Record Status"; nbBlockConfigErrors.Text = "<p>The selected Record Status setting does not exist.</p>"; return false; } return true; }
/// <summary> /// Binds the filter. /// </summary> private void BindFilter() { nreAmount.DelimitedValues = gfSettings.GetUserPreference( "Amount" ); ddlFrequency.BindToDefinedType( DefinedTypeCache.Read( Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY.AsGuid() ) ); ddlFrequency.Items.Insert( 0, new ListItem( string.Empty, string.Empty ) ); string freqPreference = gfSettings.GetUserPreference( "Frequency" ); if ( !string.IsNullOrWhiteSpace( freqPreference )) { ddlFrequency.SetValue( freqPreference ); } drpDates.DelimitedValues = gfSettings.GetUserPreference( "Created" ); var accountService = new FinancialAccountService( new RockContext() ); var accounts = accountService .Queryable().AsNoTracking() .Where( a => a.IsActive ); ddlAccount.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( FinancialAccount account in accounts.OrderBy( a => a.Order ) ) { ListItem li = new ListItem( account.Name, account.Id.ToString() ); li.Selected = account.Id.ToString() == gfSettings.GetUserPreference( "Account" ); ddlAccount.Items.Add( li ); } cbIncludeInactive.Checked = !string.IsNullOrWhiteSpace( gfSettings.GetUserPreference( "Include Inactive" ) ); }
/// <summary> /// Gets the accounts. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> private IQueryable <FinancialAccount> GetAccounts(RockContext rockContext) { int?parentAccountId = PageParameter("AccountId").AsIntegerOrNull(); if (parentAccountId.HasValue) { lActionTitle.Text = "Child Accounts".FormatAsHtmlTitle(); } else { lActionTitle.Text = "List Accounts".FormatAsHtmlTitle(); } var accountService = new FinancialAccountService(rockContext); SortProperty sortProperty = rGridAccount.SortProperty; var accountQuery = accountService.Queryable(); if (parentAccountId.HasValue) { accountQuery = accountQuery.Where(account => account.ParentAccountId == parentAccountId.Value); } string accountNameFilter = rAccountFilter.GetUserPreference("Account Name"); if (!string.IsNullOrEmpty(accountNameFilter)) { accountQuery = accountQuery.Where(account => account.Name.Contains(accountNameFilter)); } int campusId = int.MinValue; if (int.TryParse(rAccountFilter.GetUserPreference("Campus"), out campusId)) { accountQuery = accountQuery.Where(account => account.Campus.Id == campusId); } string publicFilter = rAccountFilter.GetUserPreference("Public"); if (!string.IsNullOrWhiteSpace(publicFilter)) { accountQuery = accountQuery.Where(account => (account.IsPublic ?? false) == (publicFilter == "Yes")); } string activeFilter = rAccountFilter.GetUserPreference("Active"); if (!string.IsNullOrWhiteSpace(activeFilter)) { accountQuery = accountQuery.Where(account => account.IsActive == (activeFilter == "Yes")); } string taxDeductibleFilter = rAccountFilter.GetUserPreference("Tax Deductible"); if (!string.IsNullOrWhiteSpace(taxDeductibleFilter)) { accountQuery = accountQuery.Where(account => account.IsTaxDeductible == (taxDeductibleFilter == "Yes")); } accountQuery = accountQuery.OrderBy(a => a.Order).ThenBy(f => f.Name); return(accountQuery); }
/// <summary> /// Processes the payments. /// </summary> /// <param name="gateway">The gateway.</param> /// <param name="batchNamePrefix">The batch name prefix.</param> /// <param name="payments">The payments.</param> /// <param name="batchUrlFormat">The batch URL format.</param> /// <param name="receiptEmail">The receipt email.</param> /// <returns></returns> public static string ProcessPayments( FinancialGateway gateway, string batchNamePrefix, List<Payment> payments, string batchUrlFormat = "", Guid? receiptEmail = null ) { int totalPayments = 0; int totalAlreadyDownloaded = 0; int totalNoScheduledTransaction = 0; int totalAdded = 0; int totalReversals = 0; int totalStatusChanges = 0; var batches = new List<FinancialBatch>(); var batchSummary = new Dictionary<Guid, List<Decimal>>(); var initialControlAmounts = new Dictionary<Guid, decimal>(); var txnPersonNames = new Dictionary<Guid, string>(); var gatewayComponent = gateway.GetGatewayComponent(); var newTransactions = new List<FinancialTransaction>(); using ( var rockContext = new RockContext() ) { var accountService = new FinancialAccountService( rockContext ); var txnService = new FinancialTransactionService( rockContext ); var batchService = new FinancialBatchService( rockContext ); var scheduledTxnService = new FinancialScheduledTransactionService( rockContext ); var contributionTxnType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid() ); var defaultAccount = accountService.Queryable() .Where( a => a.IsActive && !a.ParentAccountId.HasValue && ( !a.StartDate.HasValue || a.StartDate.Value <= RockDateTime.Now ) && ( !a.EndDate.HasValue || a.EndDate.Value >= RockDateTime.Now ) ) .OrderBy( a => a.Order ) .FirstOrDefault(); var batchTxnChanges = new Dictionary<Guid, List<string>>(); var batchBatchChanges = new Dictionary<Guid, List<string>>(); var scheduledTransactionIds = new List<int>(); foreach ( var payment in payments.Where( p => p.Amount > 0.0M ) ) { totalPayments++; var scheduledTransaction = scheduledTxnService.GetByScheduleId( payment.GatewayScheduleId ); if ( scheduledTransaction != null ) { // Find existing payments with same transaction code var txns = txnService .Queryable( "TransactionDetails" ) .Where( t => t.TransactionCode == payment.TransactionCode ) .ToList(); // Calculate whether a transaction needs to be added var txnAmount = CalculateTransactionAmount( payment, txns ); if ( txnAmount != 0.0M ) { scheduledTransactionIds.Add( scheduledTransaction.Id ); if ( payment.ScheduleActive.HasValue ) { scheduledTransaction.IsActive = payment.ScheduleActive.Value; } var transaction = new FinancialTransaction(); transaction.FinancialPaymentDetail = new FinancialPaymentDetail(); transaction.Guid = Guid.NewGuid(); transaction.TransactionCode = payment.TransactionCode; transaction.TransactionDateTime = payment.TransactionDateTime; transaction.Status = payment.Status; transaction.StatusMessage = payment.StatusMessage; transaction.ScheduledTransactionId = scheduledTransaction.Id; transaction.AuthorizedPersonAliasId = scheduledTransaction.AuthorizedPersonAliasId; transaction.SourceTypeValueId = scheduledTransaction.SourceTypeValueId; txnPersonNames.Add( transaction.Guid, scheduledTransaction.AuthorizedPersonAlias.Person.FullName ); transaction.FinancialGatewayId = gateway.Id; transaction.TransactionTypeValueId = contributionTxnType.Id; if ( txnAmount < 0.0M ) { transaction.Summary = "Reversal for previous transaction that failed during processing." + Environment.NewLine; } var currencyTypeValue = payment.CurrencyTypeValue; var creditCardTypevalue = payment.CreditCardTypeValue; if ( scheduledTransaction.FinancialPaymentDetail != null ) { if ( currencyTypeValue == null && scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue ) { currencyTypeValue = DefinedValueCache.Read( scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId.Value ); } if ( creditCardTypevalue == null && scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId.HasValue ) { creditCardTypevalue = DefinedValueCache.Read( scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId.Value ); } transaction.FinancialPaymentDetail.AccountNumberMasked = scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked; transaction.FinancialPaymentDetail.NameOnCardEncrypted = scheduledTransaction.FinancialPaymentDetail.NameOnCardEncrypted; transaction.FinancialPaymentDetail.ExpirationMonthEncrypted = scheduledTransaction.FinancialPaymentDetail.ExpirationMonthEncrypted; transaction.FinancialPaymentDetail.ExpirationYearEncrypted = scheduledTransaction.FinancialPaymentDetail.ExpirationYearEncrypted; transaction.FinancialPaymentDetail.BillingLocationId = scheduledTransaction.FinancialPaymentDetail.BillingLocationId; } if ( currencyTypeValue != null ) { transaction.FinancialPaymentDetail.CurrencyTypeValueId = currencyTypeValue.Id; } if ( creditCardTypevalue != null ) { transaction.FinancialPaymentDetail.CreditCardTypeValueId = creditCardTypevalue.Id; } // Try to allocate the amount of the transaction based on the current scheduled transaction accounts decimal remainingAmount = Math.Abs( txnAmount ); foreach ( var detail in scheduledTransaction.ScheduledTransactionDetails.Where( d => d.Amount != 0.0M ) ) { var transactionDetail = new FinancialTransactionDetail(); transactionDetail.AccountId = detail.AccountId; if ( detail.Amount <= remainingAmount ) { // If the configured amount for this account is less than or equal to the remaining // amount, allocate the configured amount transactionDetail.Amount = detail.Amount; remainingAmount -= detail.Amount; } else { // If the configured amount is greater than the remaining amount, only allocate // the remaining amount transaction.Summary += "Note: Downloaded transaction amount was less than the configured allocation amounts for the Scheduled Transaction."; transactionDetail.Amount = remainingAmount; transactionDetail.Summary = "Note: The downloaded amount was not enough to apply the configured amount to this account."; remainingAmount = 0.0M; } transaction.TransactionDetails.Add( transactionDetail ); if ( remainingAmount <= 0.0M ) { // If there's no amount left, break out of details break; } } // If there's still amount left after allocating based on current config, add the remainder // to the account that was configured for the most amount if ( remainingAmount > 0.0M ) { transaction.Summary += "Note: Downloaded transaction amount was greater than the configured allocation amounts for the Scheduled Transaction."; var transactionDetail = transaction.TransactionDetails .OrderByDescending( d => d.Amount ) .FirstOrDefault(); if ( transactionDetail == null && defaultAccount != null ) { transactionDetail = new FinancialTransactionDetail(); transactionDetail.AccountId = defaultAccount.Id; transaction.TransactionDetails.Add( transactionDetail ); } if ( transactionDetail != null ) { transactionDetail.Amount += remainingAmount; transactionDetail.Summary = "Note: Extra amount was applied to this account."; } } // If the amount to apply was negative, update all details to be negative (absolute value was used when allocating to accounts) if ( txnAmount < 0.0M ) { foreach ( var txnDetail in transaction.TransactionDetails ) { txnDetail.Amount = 0 - txnDetail.Amount; } } // Get the batch var batch = batchService.Get( batchNamePrefix, currencyTypeValue, creditCardTypevalue, transaction.TransactionDateTime.Value, gateway.GetBatchTimeOffset(), batches ); var batchChanges = new List<string>(); if ( batch.Id != 0 ) { initialControlAmounts.AddOrIgnore( batch.Guid, batch.ControlAmount ); } batch.ControlAmount += transaction.TotalAmount; batch.Transactions.Add( transaction ); if ( txnAmount > 0.0M && receiptEmail.HasValue ) { newTransactions.Add( transaction ); } // Add summary if ( !batchSummary.ContainsKey( batch.Guid ) ) { batchSummary.Add( batch.Guid, new List<Decimal>() ); } batchSummary[batch.Guid].Add( txnAmount ); if ( txnAmount > 0.0M ) { totalAdded++; } else { totalReversals++; } } else { totalAlreadyDownloaded++; foreach ( var txn in txns.Where( t => t.Status != payment.Status || t.StatusMessage != payment.StatusMessage ) ) { txn.Status = payment.Status; txn.StatusMessage = payment.StatusMessage; totalStatusChanges++; } } } else { totalNoScheduledTransaction++; } } rockContext.SaveChanges(); // Queue a transaction to update the status of all affected scheduled transactions var updatePaymentStatusTxn = new Rock.Transactions.UpdatePaymentStatusTransaction( gateway.Id, scheduledTransactionIds ); Rock.Transactions.RockQueue.TransactionQueue.Enqueue( updatePaymentStatusTxn ); if ( receiptEmail.HasValue ) { // Queue a transaction to send receipts var newTransactionIds = newTransactions.Select( t => t.Id ).ToList(); var sendPaymentReceiptsTxn = new Rock.Transactions.SendPaymentReceipts( receiptEmail.Value, newTransactionIds ); Rock.Transactions.RockQueue.TransactionQueue.Enqueue( sendPaymentReceiptsTxn ); } } StringBuilder sb = new StringBuilder(); sb.AppendFormat( "<li>{0} {1} downloaded.</li>", totalPayments.ToString( "N0" ), ( totalPayments == 1 ? "payment" : "payments" ) ); if ( totalAlreadyDownloaded > 0 ) { sb.AppendFormat( "<li>{0} {1} previously downloaded and {2} already been added.</li>", totalAlreadyDownloaded.ToString( "N0" ), ( totalAlreadyDownloaded == 1 ? "payment was" : "payments were" ), ( totalAlreadyDownloaded == 1 ? "has" : "have" ) ); } if ( totalStatusChanges > 0 ) { sb.AppendFormat( "<li>{0} {1} previously downloaded but had a change of status.</li>", totalStatusChanges.ToString( "N0" ), ( totalStatusChanges == 1 ? "payment was" : "payments were" ) ); } if ( totalNoScheduledTransaction > 0 ) { sb.AppendFormat( "<li>{0} {1} could not be matched to an existing scheduled payment profile.</li>", totalNoScheduledTransaction.ToString( "N0" ), ( totalNoScheduledTransaction == 1 ? "payment" : "payments" ) ); } sb.AppendFormat( "<li>{0} {1} successfully added.</li>", totalAdded.ToString( "N0" ), ( totalAdded == 1 ? "payment was" : "payments were" ) ); if ( totalReversals > 0 ) { sb.AppendFormat( "<li>{0} {1} added as a reversal to a previous transaction.</li>", totalReversals.ToString( "N0" ), ( totalReversals == 1 ? "payment was" : "payments were" ) ); } if ( totalStatusChanges > 0 ) { sb.AppendFormat( "<li>{0} {1} previously downloaded but had a change of status.</li>", totalStatusChanges.ToString( "N0" ), ( totalStatusChanges == 1 ? "payment was" : "payments were" ) ); } foreach ( var batchItem in batchSummary ) { int items = batchItem.Value.Count; if ( items > 0 ) { var batch = batches .Where( b => b.Guid.Equals( batchItem.Key ) ) .FirstOrDefault(); string batchName = string.Format( "'{0} ({1})'", batch.Name, batch.BatchStartDateTime.Value.ToString( "d" ) ); if ( !string.IsNullOrWhiteSpace( batchUrlFormat ) ) { batchName = string.Format( "<a href='{0}'>{1}</a>", string.Format( batchUrlFormat, batch.Id ), batchName ); } decimal sum = batchItem.Value.Sum(); string summaryformat = items == 1 ? "<li>{0} transaction of {1} was added to the {2} batch.</li>" : "<li>{0} transactions totaling {1} were added to the {2} batch</li>"; sb.AppendFormat( summaryformat, items.ToString( "N0" ), sum.FormatAsCurrency(), batchName ); } } return sb.ToString(); }
private void LoadAccounts() { var rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); List<Guid> selectedAccounts = new List<Guid>(); ; if ( !string.IsNullOrWhiteSpace( GetAttributeValue( "Accounts" ) ) ) { selectedAccounts = GetAttributeValue( "Accounts" ).Split( ',' ).Select( Guid.Parse ).ToList(); } var accounts = accountService.Queryable() .Where( a => selectedAccounts.Contains( a.Guid ) ) .OrderBy( a => a.Order ); foreach ( var account in accounts.ToList() ) { ListItem checkbox = new ListItem(account.Name, account.Id.ToString(), true); checkbox.Selected = true; cblAccounts.Items.Add( checkbox ); } }
/// <summary> /// Shows the detail. /// </summary> private void ShowDetail() { var transactionTypes = BindTransactionTypes(); BindAccounts(); // Load values from the system settings var givingAutomationSetting = GivingAutomationSettings.LoadGivingAutomationSettings(); var savedTransactionTypeGuids = givingAutomationSetting.TransactionTypeGuids ?? new List <Guid> { Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid() }; var savedTransactionTypeGuidStrings = savedTransactionTypeGuids.Select(g => g.ToString()) .Intersect(transactionTypes.Select(dv => dv.Guid.ToString())); var savedAccountGuids = givingAutomationSetting.FinancialAccountGuids ?? new List <Guid>(); var accounts = new List <FinancialAccount>(); var areChildAccountsIncluded = givingAutomationSetting.AreChildAccountsIncluded ?? false; if (savedAccountGuids.Any()) { using (var rockContext = new RockContext()) { var accountService = new FinancialAccountService(rockContext); accounts = accountService.Queryable() .AsNoTracking() .Where(a => savedAccountGuids.Contains(a.Guid)) .ToList(); } } // Sync the system setting values to the controls divAccounts.Visible = savedAccountGuids.Any(); apGivingAutomationAccounts.SetValues(accounts); rblAccountTypes.SetValue(savedAccountGuids.Any() ? AccountTypes_Custom : AccountTypes_AllTaxDeductible); cbGivingAutomationIncludeChildAccounts.Checked = areChildAccountsIncluded; cblTransactionTypes.SetValues(savedTransactionTypeGuidStrings); // Main Giving Automation Settings cbEnableGivingAutomation.Checked = givingAutomationSetting.GivingAutomationJobSettings.IsEnabled; dwpDaysToUpdateClassifications.SelectedDaysOfWeek = givingAutomationSetting.GivingClassificationSettings.RunDays?.ToList(); // Giving Journey Settings dwpDaysToUpdateGivingJourneys.SelectedDaysOfWeek = givingAutomationSetting.GivingJourneySettings.DaysToUpdateGivingJourneys?.ToList(); nbFormerGiverNoContributionInTheLastDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.FormerGiverNoContributionInTheLastDays; nbFormerGiverMedianFrequencyLessThanDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.FormerGiverMedianFrequencyLessThanDays; nbLapsedGiverNoContributionInTheLastDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.LapsedGiverNoContributionInTheLastDays; nbLapsedGiverMedianFrequencyLessThanDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.LapsedGiverMedianFrequencyLessThanDays; nreNewGiverContributionCountBetween.LowerValue = givingAutomationSetting.GivingJourneySettings.NewGiverContributionCountBetweenMinimum; nreNewGiverContributionCountBetween.UpperValue = givingAutomationSetting.GivingJourneySettings.NewGiverContributionCountBetweenMaximum; nbNewGiverFirstGiftInLastDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.NewGiverFirstGiftInTheLastDays; nreOccasionalGiverMedianFrequencyDays.LowerValue = givingAutomationSetting.GivingJourneySettings.OccasionalGiverMedianFrequencyDaysMinimum; nreOccasionalGiverMedianFrequencyDays.UpperValue = givingAutomationSetting.GivingJourneySettings.OccasionalGiverMedianFrequencyDaysMaximum; nbConsistentGiverMedianLessThanDays.IntegerValue = givingAutomationSetting.GivingJourneySettings.ConsistentGiverMedianLessThanDays; nbGlobalRepeatPreventionDuration.Text = givingAutomationSetting.GivingAlertingSettings.GlobalRepeatPreventionDurationDays.ToStringSafe(); nbGratitudeRepeatPreventionDuration.Text = givingAutomationSetting.GivingAlertingSettings.GratitudeRepeatPreventionDurationDays.ToStringSafe(); nbFollowupRepeatPreventionDuration.Text = givingAutomationSetting.GivingAlertingSettings.FollowupRepeatPreventionDurationDays.ToStringSafe(); BindAlerts(); }
/// <summary>Process all transactions (payments) from Service Reef.</summary> /// <param name="message">The message that is returned depending on the result.</param> /// <param name="state">The state of the process.</param> /// <returns><see cref="WorkerResultStatus"/></returns> public void Execute(IJobExecutionContext context) { RockContext dbContext = new RockContext(); FinancialBatchService financialBatchService = new FinancialBatchService(dbContext); PersonService personService = new PersonService(dbContext); PersonAliasService personAliasService = new PersonAliasService(dbContext); FinancialAccountService financialAccountService = new FinancialAccountService(dbContext); FinancialAccountService accountService = new FinancialAccountService(dbContext); FinancialTransactionService financialTransactionService = new FinancialTransactionService(dbContext); FinancialGatewayService financialGatewayService = new FinancialGatewayService(dbContext); DefinedValueService definedValueService = new DefinedValueService(dbContext); DefinedTypeService definedTypeService = new DefinedTypeService(dbContext); TransactionService transactionService = new TransactionService(new PayPalReporting.Data.PayPalReportingContext()); // Get the datamap for loading attributes JobDataMap dataMap = context.JobDetail.JobDataMap; String warnings = string.Empty; FinancialBatch batch = null; Double totalAmount = 0; var total = 1; var processed = 0; try { DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||"); String SRApiKey = Encryption.DecryptString(dataMap.GetString("ServiceReefAPIKey")); String SRApiSecret = Encryption.DecryptString(dataMap.GetString("ServiceReefAPISecret")); String SRApiUrl = dataMap.GetString("ServiceReefAPIURL"); DefinedValueCache transactionSource = DefinedValueCache.Read(dataMap.GetString("TransactionSource").AsGuid(), dbContext); DefinedValueCache connectionStatus = DefinedValueCache.Read(dataMap.GetString("ConnectionStatus").AsGuid(), dbContext); DefinedValueCache contribution = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION); // Setup some lookups DefinedTypeCache creditCards = DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE.AsGuid(), dbContext); DefinedTypeCache tenderType = DefinedTypeCache.Get(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE.AsGuid(), dbContext); FinancialAccount specialFund = accountService.Get(dataMap.GetString("Account").AsGuid()); FinancialGateway gateway = financialGatewayService.Get(dataMap.GetString("FinancialGateway").AsGuid()); List <FinancialAccount> trips = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList(); // Get the trips DefinedValueCache serviceReefAccountType = DefinedValueCache.Get(dataMap.Get("ServiceReefAccountType").ToString().AsGuid()); // Setup the ServiceReef API Client var client = new RestClient(SRApiUrl); client.Authenticator = new HMACAuthenticator(SRApiKey, SRApiSecret); // Get all payments from ServiceReef var request = new RestRequest("v1/payments", Method.GET); request.AddParameter("pageSize", 100); if (dateRange.Start.HasValue) { request.AddParameter("startDate", dateRange.Start.Value.ToString("o")); } if (dateRange.End.HasValue) { request.AddParameter("endDate", dateRange.End.Value.ToString("o")); } request.AddParameter("page", 1); while (total > processed) { var response = client.Execute <Contracts.Payments>(request); if (response.StatusCode != System.Net.HttpStatusCode.OK) { throw new Exception("ServiceReef API Response: " + response.StatusDescription + " Content Length: " + response.ContentLength); } if (response.Data != null && response.Data.PageInfo != null) { total = response.Data.PageInfo.TotalRecords; foreach (Contracts.Payments.Result result in response.Data.Results) { // Process the transaction if (result.PaymentProcessorTransactionId != null) { if (result.FirstName == null || result.LastName == null) { warnings += "Missing Firstname/Lastname for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine; processed++; continue; } FinancialAccount trip = null; // Make sure we have a sub-account to go with this transaction if (result.EventId > 0) { trip = trips.Where(t => t.GlCode == result.EventCode && t.Url == result.EventUrl).FirstOrDefault(); } if (trip == null) { if (result.EventCode == null) { warnings += "Event Code is missing on the Service Reef Trip for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine; processed++; continue; } // Create the trip subaccount FinancialAccount tripFA = new FinancialAccount(); tripFA.Name = result.EventName; // Name is limited to 50 if (tripFA.Name.Length > 50) { tripFA.Name = tripFA.Name.Substring(0, 50); } tripFA.Description = "Service Reef Event. Name: " + result.EventName + " ID: " + result.EventId; tripFA.GlCode = result.EventCode; tripFA.Url = result.EventUrl; tripFA.PublicName = result.EventName; // Public Name is limited to 50 if (tripFA.PublicName.Length > 50) { tripFA.PublicName = tripFA.PublicName.Substring(0, 50); } tripFA.IsTaxDeductible = true; tripFA.IsPublic = false; tripFA.ParentAccountId = specialFund.Id; tripFA.Order = specialFund.Order + 1; tripFA.AccountTypeValueId = serviceReefAccountType.Id; // Figure out what order it should be; foreach (FinancialAccount tmpTrip in trips) { if (tmpTrip.Name.CompareTo(tripFA.Name) < 0) { tripFA.Order++; } } financialAccountService.Add(tripFA); // Now save the trip dbContext.SaveChanges(); // Increment all the rest of the Orders financialAccountService.Queryable().Where(fa => fa.Order >= tripFA.Order && fa.Id != tripFA.Id).ToList().ForEach(c => c.Order++); dbContext.SaveChanges(); trips = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList(); trip = tripFA; } FinancialTransaction tran = financialTransactionService.Queryable().Where(tx => tx.TransactionCode == result.PaymentProcessorTransactionId).FirstOrDefault(); // We haven't processed this before so get busy! if (tran == null) { tran = new FinancialTransaction(); tran.FinancialPaymentDetail = new FinancialPaymentDetail(); if (result.Type == "CreditCard") { tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id; } else { tran.TransactionTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id; } Person person = null; // Find the person this transaction belongs to // 1. First start by determining whether this was a person // paying their application fee or contributing to themselves // because then we can just use their member info if (result.UserId > 0 && result.DonatedToUserId == result.UserId && result.DonatedToFirstName == result.FirstName && result.DonatedToLastName == result.LastName) { var memberRequest = new RestRequest("v1/members/{userId}", Method.GET); memberRequest.AddUrlSegment("userId", result.UserId.ToString()); var memberResult = client.Execute <Contracts.Member>(memberRequest); if (memberResult.Data != null && memberResult.Data.ArenaId > 0) { try { Person personMatch = personAliasService.Queryable().Where(pa => pa.AliasPersonId == memberResult.Data.ArenaId).Select(pa => pa.Person).FirstOrDefault(); if (personMatch == null) { throw new Exception("Person not found: " + memberResult.Data.ArenaId); } person = personMatch; } catch (Exception e) { warnings += "Loading the person failed transaction id " + result.TransactionId + " for " + result.FirstName + " " + result.LastName + " with the following error: " + e.Message + Environment.NewLine; processed++; continue; } } } // 2. If we didn't get a person match via their Alias Id // then just use the standard person match logic if (person == null) { String street1 = null; String postalCode = null; if (result.Address != null) { street1 = result.Address.Address1; postalCode = result.Address.Zip; } List <Person> matches = personService.GetByMatch(result.FirstName.Trim(), result.LastName.Trim(), null, result.Email, null, street1, postalCode).ToList(); if (matches.Count > 1) { // Find the oldest member record in the list person = matches.Where(p => p.ConnectionStatusValue.Value == "Member").OrderBy(p => p.Id).FirstOrDefault(); if (person == null) { // Find the oldest attendee record in the list person = matches.Where(p => p.ConnectionStatusValue.Value == "Attendee").OrderBy(p => p.Id).FirstOrDefault(); if (person == null) { person = matches.OrderBy(p => p.Id).First(); } } } else if (matches.Count == 1) { person = matches.First(); } else { // Create the person person = new Person(); person.FirstName = result.FirstName.Trim(); person.LastName = result.LastName.Trim(); if (result.Email.IsValidEmail()) { person.Email = result.Email.Trim(); } person.RecordTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id; person.ConnectionStatusValueId = connectionStatus.Id; person.RecordStatusValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id; Group family = PersonService.SaveNewPerson(person, dbContext); GroupLocation location = new GroupLocation(); location.GroupLocationTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME).Id; location.Location = new Location() { Street1 = result.Address.Address1, Street2 = result.Address.Address2, City = result.Address.City, State = result.Address.State, PostalCode = result.Address.Zip, Country = result.Address.Country }; family.CampusId = CampusCache.All().FirstOrDefault().Id; family.GroupLocations.Add(location); dbContext.SaveChanges(); } } // Get details about the transaction from our PayPal report table Transaction tx = transactionService.Get(result.PaymentProcessorTransactionId); if (tx != null) { if (tx.TenderType.Contains("ACH")) { result.Type = "ACH"; result.Method = null; } else { result.Type = "Credit Card"; result.Method = tx.TenderType; } } else { // Defaults result.Type = "Credit Card"; result.Method = "Visa"; warnings += "Unable to find transaction in _org_secc_PaypalReporting_Transaction table: " + result.TransactionId + Environment.NewLine; } // If we don't have a batch, create one if (batch == null) { batch = new FinancialBatch(); batch.BatchStartDateTime = result.Date; batch.BatchEndDateTime = DateTime.Now; batch.Name = "Service Reef Payments"; batch.Status = BatchStatus.Open; financialBatchService.Add(batch); dbContext.SaveChanges(); } // Complete the FinancialTransaction tran.AuthorizedPersonAliasId = person.PrimaryAliasId; tran.BatchId = batch.Id; tran.Summary = "F" + specialFund.Id + ":$" + result.Amount.ToString(); tran.TransactionDateTime = result.Date; tran.FinancialGatewayId = gateway.Id; FinancialTransactionDetail financialTransactionDetail = new FinancialTransactionDetail(); financialTransactionDetail.AccountId = trip.Id; financialTransactionDetail.Amount = result.Amount.ToString().AsDecimal(); tran.TransactionDetails.Add(financialTransactionDetail); tran.TransactionTypeValueId = contribution.Id; tran.FinancialPaymentDetail = new FinancialPaymentDetail(); tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(type => type.Value.ToLower() == result.Type.ToLower()).FirstOrDefault().Id; if (result.Method != null) { tran.FinancialPaymentDetail.CreditCardTypeValueId = creditCards.DefinedValues.Where(card => card.Value.ToLower() == result.Method.ToLower()).FirstOrDefault().Id; } tran.TransactionCode = result.PaymentProcessorTransactionId; tran.SourceTypeValueId = transactionSource.Id; financialTransactionService.Add(tran); dbContext.SaveChanges(); totalAmount += result.Amount; } } processed++; } } else { total = 0; } // Update the page number for the next request var pageParam = request.Parameters.Where(p => p.Name == "page").FirstOrDefault(); pageParam.Value = (int)pageParam.Value + 1; } } catch (Exception ex) { throw new Exception("ServiceReef Job Failed", ex); } finally { if (batch != null && totalAmount > 0) { batch.ControlAmount = (Decimal)totalAmount; } dbContext.SaveChanges(); } if (warnings.Length > 0) { throw new Exception(warnings); } context.Result = "Successfully imported " + processed + " transactions."; }
/// <summary> /// Binds the filter. /// </summary> private void BindFilter() { drpDates.DelimitedValues = gfTransactions.GetUserPreference( "Date Range" ); nbRowLimit.Text = gfTransactions.GetUserPreference( "Row Limit" ); nreAmount.DelimitedValues = gfTransactions.GetUserPreference( "Amount Range" ); tbTransactionCode.Text = gfTransactions.GetUserPreference( "Transaction Code" ); var accountService = new FinancialAccountService( new RockContext() ); ddlAccount.Items.Add( new ListItem( string.Empty, string.Empty ) ); foreach ( FinancialAccount account in accountService.Queryable() ) { ListItem li = new ListItem( account.Name, account.Id.ToString() ); li.Selected = account.Id.ToString() == gfTransactions.GetUserPreference( "Account" ); ddlAccount.Items.Add( li ); } BindDefinedTypeDropdown( ddlTransactionType, new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_TYPE ), "Transaction Type" ); BindDefinedTypeDropdown( ddlCurrencyType, new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE ), "Currency Type" ); BindDefinedTypeDropdown( ddlCreditCardType, new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE ), "Credit Card Type" ); BindDefinedTypeDropdown( ddlSourceType, new Guid( Rock.SystemGuid.DefinedType.FINANCIAL_SOURCE_TYPE ), "Source Type" ); }
/// <summary> /// Loads the accounts. /// </summary> private void LoadAccounts() { var rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService( rockContext ); List<Guid> selectedAccounts = new List<Guid>(); if ( !string.IsNullOrWhiteSpace( GetAttributeValue( "Accounts" ) ) ) { selectedAccounts = GetAttributeValue( "Accounts" ).Split( ',' ).AsGuidList(); } var accountList = accountService.Queryable() .Where( a => selectedAccounts.Contains( a.Guid ) ) .OrderBy( a => a.Order ) .Select( a => new { a.Id, a.PublicName } ).ToList(); if ( accountList.Any() ) { foreach ( var account in accountList ) { ListItem checkbox = new ListItem( account.PublicName, account.Id.ToString(), true ); checkbox.Selected = true; cblAccounts.Items.Add( checkbox ); } } else { cblAccounts.Items.Clear(); } // only show Account Checkbox list if there are accounts are configured for the block cblAccounts.Visible = accountList.Any(); }
/// <summary> /// Adds the family giving records. /// <param name="elemGiving">The giving element.</param> /// </summary> /// <param name="elemGiving">The giving element.</param> /// <param name="familyName">The family name.</param> /// <param name="rockContext">The rock context.</param> private void AddFamilyGiving( XElement elemGiving, string familyName, RockContext rockContext ) { // return from here if there's not a startGiving date, account amount details or a person Guid. if ( elemGiving == null || elemGiving.Attribute( "startGiving" ) == null || elemGiving.Attribute( "accountAmount" ) == null || elemGiving.Attribute( "personGuid" ) == null ) { return; } // get some variables we'll need to create the giving records DateTime startingDate = DateTime.Parse( elemGiving.Attribute( "startGiving" ).Value.Trim(), new CultureInfo( "en-US" ) ); DateTime endDate = RockDateTime.Now; if ( elemGiving.Attribute( "endGiving" ) != null ) { DateTime.TryParse( elemGiving.Attribute( "endGiving" ).Value.Trim(), out endDate ); } else if ( elemGiving.Attribute( "endingGivingWeeksAgo" ) != null ) { int endingWeeksAgo = 0; int.TryParse( elemGiving.Attribute( "endingGivingWeeksAgo" ).Value.Trim(), out endingWeeksAgo ); endDate = RockDateTime.Now.AddDays( -7 * endingWeeksAgo ); } int percentGive = 100; if ( elemGiving.Attribute( "percentGive" ) != null ) { int.TryParse( elemGiving.Attribute( "percentGive" ).Value.Trim(), out percentGive ); } int growRatePercent = 0; if ( elemGiving.Attribute( "growRatePercent" ) != null ) { int.TryParse( elemGiving.Attribute( "growRatePercent" ).Value.Trim(), out growRatePercent ); } int growFrequencyWeeks = 0; if ( elemGiving.Attribute( "growFrequencyWeeks" ) != null ) { int.TryParse( elemGiving.Attribute( "growFrequencyWeeks" ).Value.Trim(), out growFrequencyWeeks ); } int specialGiftPercent = 0; if ( elemGiving.Attribute( "specialGiftPercent" ) != null ) { int.TryParse( elemGiving.Attribute( "specialGiftPercent" ).Value.Trim(), out specialGiftPercent ); } Frequency frequency; if ( elemGiving.Attribute( "frequency" ) != null ) { Enum.TryParse( elemGiving.Attribute( "frequency" ).Value.Trim(), out frequency ); } else { frequency = Frequency.weekly; } Guid personGuid = elemGiving.Attribute( "personGuid" ).Value.Trim().AsGuid(); // Build a dictionary of FinancialAccount Ids and the amount to give to that account. Dictionary<int, decimal> accountAmountDict = new Dictionary<int, decimal>(); FinancialAccountService financialAccountService = new FinancialAccountService( rockContext ); var allAccountAmount = elemGiving.Attribute( "accountAmount" ).Value.Trim().Split(','); foreach ( var item in allAccountAmount ) { var accountAmount = item.Split(':'); decimal amount; if ( ! Decimal.TryParse( accountAmount[1], out amount ) ) { continue; // skip if not a valid decimal } var accountName = accountAmount[0].ToLower(); var financialAccount = financialAccountService.Queryable().AsNoTracking().Where( a => a.Name.ToLower() == accountName ).FirstOrDefault(); if ( financialAccount != null ) { accountAmountDict.Add(financialAccount.Id, amount ); } else { financialAccount = financialAccountService.Queryable().AsNoTracking().First(); } } // Build a circular linked list of photos to use for the fake contribution check images var circularImageList = new LinkedList<string>(); if ( elemGiving.Attribute( "imageUrls" ) != null ) { var allImageUrls = elemGiving.Attribute( "imageUrls" ).Value.Trim().Split( ',' ); foreach ( var item in allImageUrls ) { circularImageList.AddLast( item ); } } // Now create the giving data for this recipe set CreateGiving( personGuid, startingDate, endDate, frequency, percentGive, growRatePercent, growFrequencyWeeks, specialGiftPercent, accountAmountDict, circularImageList, rockContext ); AppendFormat( "{0:00}:{1:00}.{2:00} added giving data {3}<br/>", _stopwatch.Elapsed.Minutes, _stopwatch.Elapsed.Seconds, _stopwatch.Elapsed.Milliseconds / 10, familyName ); }
// checks the settings provided private bool CheckSettings() { nbBlockConfigErrors.Title = string.Empty; nbBlockConfigErrors.Text = string.Empty; // get list of selected accounts filtered by the current campus RockContext rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); if (!string.IsNullOrWhiteSpace(GetAttributeValue("Accounts"))) { Guid[] selectedAccounts = GetAttributeValue("Accounts").Split(',').Select(s => Guid.Parse(s)).ToArray();; var accounts = accountService.Queryable() .Where(a => selectedAccounts.Contains(a.Guid)); if (this.CampusId != 0) { accounts = accounts.Where(a => a.CampusId.Value == this.CampusId || a.CampusId == null); } this.Accounts = new Dictionary <int, string>(); foreach (var account in accounts.OrderBy(a => a.Order).ToList()) { this.Accounts.Add(account.Id, account.PublicName); } } else { nbBlockConfigErrors.Heading = "No Accounts Configured"; nbBlockConfigErrors.Text = "<p>There are currently no accounts configured.</p>"; return(false); } // hide cancel buttons if no homepage defined if (string.IsNullOrWhiteSpace(GetAttributeValue("Homepage"))) { lbSearchCancel.Visible = false; lbGivingUnitSelectCancel.Visible = false; lbRegisterCancel.Visible = false; lbAccountEntryCancel.Visible = false; lbSwipeCancel.Visible = false; } // get anonymous person Person anonymousPerson = null; Guid anonymousPersonAliasGuid; if (Guid.TryParse(GetAttributeValue("AnonymousPerson"), out anonymousPersonAliasGuid)) { anonymousPerson = new PersonAliasService(rockContext).Get(anonymousPersonAliasGuid).Person; } if (anonymousPerson != null) { this.AnonymousGiverPersonAliasId = anonymousPerson.PrimaryAliasId; lbGiveAnonymously.Visible = true; } else { lbGiveAnonymously.Visible = false; } _dvcConnectionStatus = DefinedValueCache.Read(GetAttributeValue("ConnectionStatus").AsGuid()); if (_dvcConnectionStatus == null) { nbBlockConfigErrors.Heading = "Invalid Connection Status"; nbBlockConfigErrors.Text = "<p>The selected Connection Status setting does not exist.</p>"; return(false); } _dvcRecordStatus = DefinedValueCache.Read(GetAttributeValue("RecordStatus").AsGuid()); if (_dvcRecordStatus == null) { nbBlockConfigErrors.Heading = "Invalid Record Status"; nbBlockConfigErrors.Text = "<p>The selected Record Status setting does not exist.</p>"; return(false); } return(true); }
/// <summary> /// Binds the profile. /// </summary> /// <param name="profileId">The profile id.</param> protected void BindGivingProfile(int profileId) { DateTime currentDate = DateTimeOffset.Now.DateTime; var accountService = new FinancialAccountService(); var activeAccounts = accountService.Queryable().Where(f => f.IsActive && (f.StartDate == null || f.StartDate <= currentDate) && (f.EndDate == null || f.EndDate <= currentDate) && f.PublicName != null && f.PublicName != ""); var accountGuids = GetAttributeValues("DefaultAccounts").Select(Guid.Parse).ToList(); var scheduledTransactionService = new FinancialScheduledTransactionService(); var transactionList = new Dictionary <FinancialAccount, decimal>(); FinancialScheduledTransaction scheduledTransaction; if (profileId != 0 && scheduledTransactionService.TryGet(profileId, out scheduledTransaction)) { // Retrieve Transaction btnFrequency.SelectedValue = scheduledTransaction.TransactionFrequencyValue.Id.ToString(); divFrequency.Visible = true; dtpStartDate.SelectedDate = scheduledTransaction.StartDate; divRecurrence.Visible = true; divLimitGifts.Visible = true; if (scheduledTransaction.NumberOfPayments != null) { chkLimitGifts.Checked = true; txtLimitNumber.Text = scheduledTransaction.NumberOfPayments.ToString(); divLimitNumber.Visible = true; } foreach (var details in scheduledTransaction.ScheduledTransactionDetails) { transactionList.Add(details.Account, details.Amount); } } else { // New Transaction IQueryable <FinancialAccount> selectedAccounts = activeAccounts; if (accountGuids.Any()) { selectedAccounts = selectedAccounts.Where(a => accountGuids.Contains(a.Guid)); } var campusId = btnCampusList.SelectedValueAsInt(); selectedAccounts = selectedAccounts.Where(f => f.CampusId == campusId || (f.CampusId == null && f.ChildAccounts.Count() == 0)); foreach (var account in selectedAccounts) { transactionList.Add(account, 0M); } } if (activeAccounts.Count() > transactionList.Count() && Convert.ToBoolean(GetAttributeValue("ShowAdditionalAccounts"))) { var unselectedAccounts = activeAccounts.Where(a => !accountGuids.Contains(a.Guid)).ToList(); if (unselectedAccounts.Any()) { btnAddAccount.DataTextField = "PublicName"; btnAddAccount.DataValueField = "Id"; btnAddAccount.DataSource = unselectedAccounts.ToList(); btnAddAccount.DataBind(); } } else { divAddAccount.Visible = false; } Session["CachedAmounts"] = transactionList; Session["CachedProfileId"] = profileId; rptAccountList.DataSource = transactionList; rptAccountList.DataBind(); spnTotal.InnerText = transactionList.Sum(d => d.Value).ToString("f2"); }