/// <summary> /// Gets the transaction details. /// </summary> /// <param name="rockContext">The rock context.</param> /// <returns></returns> protected List <FinancialTransactionDetail> GetTransactionDetails(RockContext rockContext) { var details = new List <FinancialTransactionDetail>(); var financialAccountService = new FinancialAccountService(rockContext); int defaultAccountId = financialAccountService.Get(GetAttributeValue("DefaultAccount").AsGuid()).Id; foreach (var item in Cart.Items) { int financialAccountId = item.AccountId ?? defaultAccountId; var transactionDetail = details.FirstOrDefault(d => d.AccountId == financialAccountId); if (transactionDetail == null) { transactionDetail = new FinancialTransactionDetail { Amount = 0, AccountId = financialAccountId }; details.Add(transactionDetail); } transactionDetail.Amount += item.ExtendedPrice; } return(details); }
/// <summary> /// Handles the Click event of the btnCancel 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 btnCancel_Click(object sender, EventArgs e) { if (hfAccountId.Value.Equals("0")) { int?parentAccountId = PageParameter("ParentAccountId").AsIntegerOrNull(); if (parentAccountId.HasValue) { // Cancelling on Add, and we know the parentGroupID, so we are probably in treeview mode, so navigate to the current page var qryParams = new Dictionary <string, string>(); if (parentAccountId != 0) { qryParams["AccountId"] = parentAccountId.ToString(); } qryParams["ExpandedIds"] = PageParameter("ExpandedIds"); NavigateToPage(RockPage.Guid, qryParams); } else { // Cancelling on Add. Return to Grid NavigateToPage(RockPage.Guid, null); } } else { // Cancelling on Edit. Return to Details FinancialAccountService service = new FinancialAccountService(new RockContext()); FinancialAccount account = service.Get(hfAccountId.ValueAsInt()); ShowReadonlyDetails(account); } }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; Guid?guid = value.AsGuidOrNull(); if (guid.HasValue) { bool displayPublicName = true; if (configurationValues != null && configurationValues.ContainsKey(DISPLAY_PUBLIC_NAME)) { displayPublicName = configurationValues[DISPLAY_PUBLIC_NAME].Value.AsBoolean(); } var service = new FinancialAccountService(new RockContext()); var account = service.Get(guid.Value); if (account != null) { formattedValue = displayPublicName ? account.PublicName : account.Name; } } return(base.FormatValue(parentControl, formattedValue, null, condensed)); }
/// <summary> /// Handles the Click event of the btnEdit 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 btnEdit_Click(object sender, EventArgs e) { FinancialAccountService service = new FinancialAccountService(new RockContext()); FinancialAccount account = service.Get(hfAccountId.ValueAsInt()); ShowEditDetails(account); }
/// <summary> /// Gfs the settings_ display filter value. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> protected void gfSettings_DisplayFilterValue(object sender, GridFilter.DisplayFilterValueArgs e) { switch (e.Key) { case "Amount": e.Value = NumberRangeEditor.FormatDelimitedValues(e.Value, "N2"); break; case "Frequency": int definedValueId = 0; if (int.TryParse(e.Value, out definedValueId)) { var definedValue = DefinedValueCache.Read(definedValueId); if (definedValue != null) { e.Value = definedValue.Value; } } break; case "Created": e.Value = DateRangePicker.FormatDelimitedValues(e.Value); break; case "Account": int accountId = 0; if (int.TryParse(e.Value, out accountId) && ddlAccount.Visible) { var service = new FinancialAccountService(new RockContext()); var account = service.Get(accountId); if (account != null) { e.Value = account.Name; } } else { e.Value = string.Empty; } break; case "Include Inactive": break; default: e.Value = string.Empty; break; } }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue( Control parentControl, string value, Dictionary<string, ConfigurationValue> configurationValues, bool condensed ) { string formattedValue = string.Empty; if ( !string.IsNullOrWhiteSpace( value ) ) { var service = new FinancialAccountService( new RockContext() ); var account = service.Get( new Guid( value ) ); if ( account != null ) { formattedValue = account.PublicName; } } return base.FormatValue( parentControl, formattedValue, null, condensed ); }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; if (!string.IsNullOrWhiteSpace(value)) { var service = new FinancialAccountService(); var account = service.Get(new Guid(value)); if (account != null) { formattedValue = account.PublicName; } } return(base.FormatValue(parentControl, formattedValue, null, condensed)); }
/// <summary> /// Handles the filter display for each saved user value /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <exception cref="System.NotImplementedException"></exception> protected void rFilter_DisplayFilterValue(object sender, Rock.Web.UI.Controls.GridFilter.DisplayFilterValueArgs e) { switch (e.Key) { case "Date Range": e.Value = DateRangePicker.FormatDelimitedValues(e.Value); break; case "Amount Range": e.Value = NumberRangeEditor.FormatDelimitedValues(e.Value, "N2"); break; case "Account": int accountId = 0; if (int.TryParse(e.Value, out accountId)) { var service = new FinancialAccountService(); var account = service.Get(accountId); if (account != null) { e.Value = account.Name; } } break; case "Transaction Type": case "Currency Type": case "Credit Card Type": case "Source Type": int definedValueId = 0; if (int.TryParse(e.Value, out definedValueId)) { var definedValue = DefinedValueCache.Read(definedValueId); if (definedValue != null) { e.Value = definedValue.Name; } } break; } }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue( Control parentControl, string value, Dictionary<string, ConfigurationValue> configurationValues, bool condensed ) { string formattedValue = string.Empty; Guid? guid = value.AsGuidOrNull(); if ( guid.HasValue ) { var service = new FinancialAccountService( new RockContext() ); var account = service.Get( guid.Value ); if ( account != null ) { formattedValue = account.PublicName; } } return base.FormatValue( parentControl, formattedValue, null, condensed ); }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; Guid?guid = value.AsGuidOrNull(); if (guid.HasValue) { var service = new FinancialAccountService(new RockContext()); var account = service.Get(guid.Value); if (account != null) { formattedValue = account.PublicName; } } return(base.FormatValue(parentControl, formattedValue, null, condensed)); }
/// <summary> /// Handles the Click event of the btnDelete 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 btnDelete_Click(object sender, EventArgs e) { int? parentAccountId = null; RockContext rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); AuthService authService = new AuthService(rockContext); FinancialAccount account = accountService.Get(hfAccountId.Value.AsInteger()); if (account != null) { if (!account.IsAuthorized(Authorization.EDIT, this.CurrentPerson)) { mdDeleteWarning.Show("You are not authorized to delete this account.", ModalAlertType.Information); return; } parentAccountId = account.ParentAccountId; string errorMessage; if (!accountService.CanDelete(account, out errorMessage)) { mdDeleteWarning.Show(errorMessage, ModalAlertType.Information); return; } accountService.Delete(account); rockContext.SaveChanges(); } // reload page, selecting the deleted account's parent var qryParams = new Dictionary <string, string>(); if (parentAccountId != null) { qryParams["AccountId"] = parentAccountId.ToString(); } qryParams["ExpandedIds"] = PageParameter("ExpandedIds"); NavigateToPage(RockPage.Guid, qryParams); }
/// <summary> /// Handles the Delete event of the rGridAccount 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 rGridAccount_Delete(object sender, RowEventArgs e) { var accountService = new FinancialAccountService(); var account = accountService.Get((int)e.RowKeyValue); if (account != null) { string errorMessage; if (!accountService.CanDelete(account, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } accountService.Delete(account, CurrentPersonId); accountService.Save(account, CurrentPersonId); } BindGrid(); }
/// <summary> /// Handles the Delete event of the rGridAccount 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 rGridAccount_Delete(object sender, RowEventArgs e) { var rockContext = new RockContext(); var accountService = new FinancialAccountService(rockContext); var account = accountService.Get(e.RowKeyId); if (account != null) { string errorMessage; if (!accountService.CanDelete(account, out errorMessage)) { mdGridWarning.Show(errorMessage, ModalAlertType.Information); return; } accountService.Delete(account); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Handles the Click event of the btnAddAccount 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 btnAddAccount_SelectionChanged(object sender, EventArgs e) { SaveAmounts(); var amountList = (Dictionary <FinancialAccount, Decimal>)Session["CachedAmounts"]; var accountService = new FinancialAccountService(); FinancialAccount account = accountService.Get((int)btnAddAccount.SelectedValueAsInt()); amountList.Add(account, 0M); if (btnAddAccount.Items.Count > 1) { btnAddAccount.Items.Remove(btnAddAccount.SelectedItem); btnAddAccount.Title = "Add Another Gift"; } else { btnAddAccount.Visible = false; divAddAccount.Visible = false; } RebindAmounts(amountList); }
/// <summary> /// Handles the filter display for each saved user value /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <exception cref="System.NotImplementedException"></exception> protected void rFilter_DisplayFilterValue(object sender, Rock.Web.UI.Controls.GridFilter.DisplayFilterValueArgs e) { switch (e.Key) { case "Fund": int fundId = 0; if (int.TryParse(e.Value, out fundId)) { var service = new FinancialAccountService(); var fund = service.Get(fundId); if (fund != null) { e.Value = fund.Name; } } break; case "Currency Type": case "Credit Card Type": case "Source": int definedValueId = 0; if (int.TryParse(e.Value, out definedValueId)) { var definedValue = DefinedValueCache.Read(definedValueId); if (definedValue != null) { e.Value = definedValue.Name; } } break; } }
/// <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> /// 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> /// <exception cref="System.NotImplementedException"></exception> protected void btnSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var financialPledgeService = new FinancialPledgeService(rockContext); var financialAccountService = new FinancialAccountService(rockContext); var definedValueService = new DefinedValueService(rockContext); var person = FindPerson(rockContext); FinancialPledge financialPledge = new FinancialPledge(); financialPledge.PersonAliasId = person.PrimaryAliasId; var financialAccount = financialAccountService.Get(GetAttributeValue("Account").AsGuid()); if (financialAccount != null) { financialPledge.AccountId = financialAccount.Id; } financialPledge.TotalAmount = tbTotalAmount.Text.AsDecimal(); var pledgeFrequencySelection = DefinedValueCache.Read(bddlFrequency.SelectedValue.AsInteger()); if (pledgeFrequencySelection != null) { financialPledge.PledgeFrequencyValueId = pledgeFrequencySelection.Id; } financialPledge.StartDate = drpDateRange.LowerValue ?? DateTime.MinValue; financialPledge.EndDate = drpDateRange.UpperValue ?? DateTime.MaxValue; if (sender != btnConfirm) { var duplicatePledges = financialPledgeService.Queryable() .Where(a => a.PersonAlias.PersonId == person.Id) .Where(a => a.AccountId == financialPledge.AccountId) .Where(a => a.StartDate == financialPledge.StartDate) .Where(a => a.EndDate == financialPledge.EndDate).ToList(); if (duplicatePledges.Any()) { pnlAddPledge.Visible = false; pnlConfirm.Visible = true; nbDuplicatePledgeWarning.Text = "The following pledges have already been entered for you:"; nbDuplicatePledgeWarning.Text += "<ul>"; foreach (var pledge in duplicatePledges.OrderBy(a => a.StartDate).ThenBy(a => a.Account.Name)) { nbDuplicatePledgeWarning.Text += string.Format("<li>{0} {1} {2}</li>", pledge.Account, pledge.PledgeFrequencyValue, pledge.TotalAmount); } nbDuplicatePledgeWarning.Text += "</ul>"; return; } } financialPledgeService.Add(financialPledge); rockContext.SaveChanges(); // populate account so that Liquid can access it financialPledge.Account = financialAccount; // populate PledgeFrequencyValue so that Liquid can access it financialPledge.PledgeFrequencyValue = definedValueService.Get(financialPledge.PledgeFrequencyValueId ?? 0); var mergeObjects = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(this.CurrentPerson); mergeObjects.Add("Person", person); mergeObjects.Add("FinancialPledge", financialPledge); mergeObjects.Add("PledgeFrequency", pledgeFrequencySelection); mergeObjects.Add("Account", financialAccount); lReceipt.Text = GetAttributeValue("ReceiptText").ResolveMergeFields(mergeObjects); // Resolve any dynamic url references string appRoot = ResolveRockUrl("~/"); string themeRoot = ResolveRockUrl("~~/"); lReceipt.Text = lReceipt.Text.Replace("~~/", themeRoot).Replace("~/", appRoot); // show liquid help for debug if (GetAttributeValue("EnableDebug").AsBoolean() && IsUserAuthorized(Authorization.EDIT)) { lReceipt.Text += mergeObjects.lavaDebugInfo(); } lReceipt.Visible = true; pnlAddPledge.Visible = false; pnlConfirm.Visible = false; // if a ConfirmationEmailTemplate is configured, send an email var confirmationEmailTemplateGuid = GetAttributeValue("ConfirmationEmailTemplate").AsGuidOrNull(); if (confirmationEmailTemplateGuid.HasValue) { var recipients = new List <Rock.Communication.RecipientData>(); // add person and the mergeObjects (same mergeobjects as receipt) recipients.Add(new Rock.Communication.RecipientData(person.Email, mergeObjects)); Rock.Communication.Email.Send(confirmationEmailTemplateGuid.Value, recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/")); } }
/// <summary> /// Gets the payments that have been processed for any scheduled transactions /// </summary> /// <param name="gateway">The gateway.</param> /// <param name="startDate">The start date.</param> /// <param name="endDate">The end date.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override List <Payment> GetPayments(FinancialGateway gateway, DateTime startDate, DateTime endDate, out string errorMessage) { var today = RockDateTime.Now; var lookupContext = new RockContext(); var accountLookup = new FinancialAccountService(lookupContext); var transactionLookup = new FinancialTransactionService(lookupContext); var donationUrl = GetBaseUrl(gateway, "donations", out errorMessage); var supporterUrl = GetBaseUrl(gateway, "sponsorship_supporters", out errorMessage); var categoryUrl = GetBaseUrl(gateway, "donation_categories", out errorMessage); var projectsUrl = GetBaseUrl(gateway, "projects", out errorMessage); if (donationUrl.IsNullOrWhiteSpace() || supporterUrl.IsNullOrWhiteSpace()) { // errorMessage already set return(null); } var authenticator = GetAuthenticator(gateway, out errorMessage); if (authenticator == null) { // errorMessage already set return(null); } var reachAccountMaps = DefinedTypeCache.Get(GetAttributeValue(gateway, "AccountMap")).DefinedValues; var connectionStatus = DefinedValueCache.Get(GetAttributeValue(gateway, "PersonStatus")); var reachSourceType = DefinedValueCache.Get(GetAttributeValue(gateway, "SourceType")); var defaultAccount = accountLookup.Get(GetAttributeValue(gateway, "DefaultAccount").AsGuid()); var updatePrimaryEmail = GetAttributeValue(gateway, "UpdatePrimaryEmail").AsBoolean(); if (connectionStatus == null || reachAccountMaps == null || reachSourceType == null || defaultAccount == null) { errorMessage = "The Reach Account Map, Person Status, Source Type, or Default Account is not configured correctly in gateway settings."; return(null); } var currentPage = 1; var queryHasResults = true; var skippedTransactionCount = 0; var errorMessages = new List <string>(); var newTransactions = new List <FinancialTransaction>(); var categoryResult = Api.PostRequest(categoryUrl, authenticator, null, out errorMessage); var categories = JsonConvert.DeserializeObject <List <Reporting.Category> >(categoryResult.ToStringSafe()); var projectResult = Api.PostRequest(projectsUrl, authenticator, null, out errorMessage); var projects = JsonConvert.DeserializeObject <List <Reporting.Project> >(projectResult.ToStringSafe()); if (categories == null) { // errorMessage already set return(null); } while (queryHasResults) { var parameters = new Dictionary <string, string> { { "from_date", startDate.ToString("yyyy-MM-dd") }, { "to_date", endDate.ToString("yyyy-MM-dd") }, { "per_page", "50" }, { "page", currentPage.ToString() } }; // to_date doesn't have a timestamp, so it includes transactions posted after the cutoff var donationResult = Api.PostRequest(donationUrl, authenticator, parameters, out errorMessage); var donations = JsonConvert.DeserializeObject <List <Donation> >(donationResult.ToStringSafe()); if (donations != null && donations.Any() && errorMessage.IsNullOrWhiteSpace()) { // only process completed transactions with confirmation codes and within the date range foreach (var donation in donations.Where(d => d.updated_at >= startDate && d.updated_at < endDate && d.status.Equals("complete") && d.confirmation.IsNotNullOrWhiteSpace())) { var transaction = transactionLookup.Queryable() .FirstOrDefault(t => t.FinancialGatewayId.HasValue && t.FinancialGatewayId.Value == gateway.Id && t.TransactionCode == donation.confirmation); if (transaction == null) { // find or create this person asynchronously for performance var personAlias = Api.FindPersonAsync(lookupContext, donation, connectionStatus.Id, updatePrimaryEmail); var reachAccountName = string.Empty; var donationItem = donation.line_items.FirstOrDefault(); if (donationItem != null && donationItem.referral_type.Equals("DonationOption", StringComparison.InvariantCultureIgnoreCase)) { // one-time gift, should match a known category var category = categories.FirstOrDefault(c => c.id == donationItem.referral_id); if (category != null) { reachAccountName = category.title.Trim(); } } else if (donationItem != null && donationItem.referral_type.Equals("Project", StringComparison.InvariantCultureIgnoreCase)) { // one-time gift, should match a known project var project = projects.FirstOrDefault(c => c.id == donationItem.referral_id); if (project != null) { reachAccountName = string.Format("PROJECT {0}", project.title.Trim()); } } else { // recurring gift, lookup the sponsor info var referralId = donation.referral_id ?? donationItem.referral_id; var supporterResults = Api.PostRequest(string.Format("{0}/{1}", supporterUrl, referralId), authenticator, null, out errorMessage); var supporter = JsonConvert.DeserializeObject <Supporter>(supporterResults.ToStringSafe()); if (supporter != null) { var place = supporter.sponsorship?.place?.title; var sponsorshipType = supporter.sponsorship?.sponsorship_type_title; var shareType = supporter.share_type_id; string shareTypeName; switch (shareType) { case "668": shareTypeName = "Primary"; break; case "669": shareTypeName = "Secondary"; break; default: shareTypeName = string.Empty; break; } reachAccountName = string.Format("{0} {1} {2}", place, sponsorshipType, shareTypeName).Trim(); } } int?rockAccountId = defaultAccount.Id; var accountMapping = reachAccountMaps.FirstOrDefault(v => v.Value.Equals(reachAccountName, StringComparison.CurrentCultureIgnoreCase)); if (accountMapping != null) { var accountGuid = accountMapping.GetAttributeValue("RockAccount").AsGuidOrNull(); if (accountGuid.HasValue) { rockAccountId = accountLookup.Get(( Guid )accountGuid).Id; } } // verify person alias was found or created personAlias.Wait(); if (!personAlias.Result.HasValue) { var infoMessage = string.Format("{0} Reach import skipped {1} {2}'s donation {3} for {4} because their record could not be found or created", endDate.ToString("d"), donation.first_name, donation.last_name, donation.confirmation, reachAccountName); ExceptionLogService.LogException(new Exception(infoMessage), null); continue; } // create the transaction var summary = string.Format("Reach Donation for {0} from {1} using {2} on {3} ({4})", reachAccountName, donation.name, donation.payment_method, donation.updated_at, donation.token); transaction = new FinancialTransaction { TransactionDateTime = donation.updated_at, ProcessedDateTime = donation.updated_at, TransactionCode = donation.confirmation, Summary = summary, SourceTypeValueId = reachSourceType.Id, TransactionTypeValueId = contributionTypeId, Guid = Guid.NewGuid(), CreatedDateTime = today, ModifiedDateTime = today, AuthorizedPersonAliasId = personAlias.Result.Value, FinancialGatewayId = gateway.Id, ForeignId = donation.id, FinancialPaymentDetail = new FinancialPaymentDetail(), TransactionDetails = new List <FinancialTransactionDetail> { new FinancialTransactionDetail { AccountId = (int)rockAccountId, Amount = (decimal)donation.amount, Summary = summary, Guid = Guid.NewGuid(), CreatedDateTime = today, ModifiedDateTime = today } } }; newTransactions.Add(transaction); } else if (transaction != null) { skippedTransactionCount++; } } } else { queryHasResults = false; } currentPage++; } if (skippedTransactionCount > 0) { ExceptionLogService.LogException(new Exception(string.Format("{0} Reach import skipped downloading {1} transactions because they already exist", endDate.ToString("d"), skippedTransactionCount)), null); } if (newTransactions.Any()) { using (var rockContext = new RockContext()) { // create batch and add transactions var batchPrefix = GetAttributeValue(gateway, "BatchPrefix"); var batchDate = newTransactions.GroupBy(t => t.TransactionDateTime.Value.Date).OrderByDescending(t => t.Count()) .Select(g => g.Key).FirstOrDefault(); var batch = new FinancialBatchService(rockContext).GetByNameAndDate(string.Format("{0} {1}", batchPrefix, batchDate.ToString("d")), endDate, gateway.GetBatchTimeOffset()); batch.BatchStartDateTime = batchDate; batch.BatchEndDateTime = endDate; batch.Note = string.Format("{0} transactions downloaded starting {1} to {2}", batchPrefix, startDate, endDate); batch.ControlAmount += newTransactions.Select(t => t.TotalAmount).Sum(); var currentChanges = 0; foreach (var transaction in newTransactions) { // save in large batches so it doesn't overload context batch.Transactions.Add(transaction); if (currentChanges++ > 100) { rockContext.SaveChanges(disablePrePostProcessing: true); currentChanges = 0; } } // by default Rock associates with the current person rockContext.SaveChanges(disablePrePostProcessing: true); } } if (errorMessages.Any()) { errorMessage = string.Join("<br>", errorMessages); } return(new List <Payment>()); }
/// <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> /// <exception cref="System.NotImplementedException"></exception> protected void btnSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var financialPledgeService = new FinancialPledgeService( rockContext ); var financialAccountService = new FinancialAccountService( rockContext ); var definedValueService = new DefinedValueService( rockContext ); var person = FindPerson( rockContext ); FinancialPledge financialPledge = new FinancialPledge(); financialPledge.PersonId = person.Id; var financialAccount = financialAccountService.Get( GetAttributeValue( "Account" ).AsGuid() ); if ( financialAccount != null ) { financialPledge.AccountId = financialAccount.Id; } financialPledge.TotalAmount = tbTotalAmount.Text.AsDecimal(); var pledgeFrequencySelection = DefinedValueCache.Read( bddlFrequency.SelectedValue.AsInteger() ); if ( pledgeFrequencySelection != null ) { financialPledge.PledgeFrequencyValueId = pledgeFrequencySelection.Id; } financialPledge.StartDate = drpDateRange.LowerValue ?? DateTime.MinValue; financialPledge.EndDate = drpDateRange.UpperValue ?? DateTime.MaxValue; if ( sender != btnConfirm ) { var duplicatePledges = financialPledgeService.Queryable() .Where( a => a.PersonId == person.Id ) .Where( a => a.AccountId == financialPledge.AccountId ) .Where( a => a.StartDate == financialPledge.StartDate ) .Where( a => a.EndDate == financialPledge.EndDate ).ToList(); if ( duplicatePledges.Any() ) { pnlAddPledge.Visible = false; pnlConfirm.Visible = true; nbDuplicatePledgeWarning.Text = "The following pledges have already been entered for you:"; nbDuplicatePledgeWarning.Text += "<ul>"; foreach ( var pledge in duplicatePledges.OrderBy( a => a.StartDate ).ThenBy( a => a.Account.Name ) ) { nbDuplicatePledgeWarning.Text += string.Format( "<li>{0} {1} {2}</li>", pledge.Account, pledge.PledgeFrequencyValue, pledge.TotalAmount ); } nbDuplicatePledgeWarning.Text += "</ul>"; return; } } financialPledgeService.Add( financialPledge ); rockContext.SaveChanges(); // populate account so that Liquid can access it financialPledge.Account = financialAccount; // populate PledgeFrequencyValue so that Liquid can access it financialPledge.PledgeFrequencyValue = definedValueService.Get( financialPledge.PledgeFrequencyValueId ?? 0 ); var mergeObjects = new Dictionary<string, object>(); mergeObjects.Add( "Person", person ); mergeObjects.Add( "FinancialPledge", financialPledge ); mergeObjects.Add( "PledgeFrequency", pledgeFrequencySelection ); mergeObjects.Add( "Account", financialAccount ); lReceipt.Text = GetAttributeValue( "ReceiptText" ).ResolveMergeFields( mergeObjects ); // show liquid help for debug if ( GetAttributeValue( "EnableDebug" ).AsBooleanOrNull() ?? false ) { StringBuilder debugInfo = new StringBuilder(); debugInfo.Append( "<p /><div class='alert alert-info'><h4>Debug Info</h4>" ); debugInfo.Append( "<pre>" ); debugInfo.Append( "<p /><strong>Liquid Data</strong> <br>" ); debugInfo.Append( mergeObjects.LiquidHelpText() + "</pre>" ); debugInfo.Append( "</div>" ); lReceipt.Text += debugInfo.ToString(); } lReceipt.Visible = true; pnlAddPledge.Visible = false; pnlConfirm.Visible = false; // if a ConfirmationEmailTemplate is configured, send an email var confirmationEmailTemplateGuid = GetAttributeValue( "ConfirmationEmailTemplate" ).AsGuidOrNull(); if ( confirmationEmailTemplateGuid.HasValue ) { var recipients = new Dictionary<string, Dictionary<string, object>>(); // add person and the mergeObjects (same mergeobjects as receipt) recipients.Add( person.Email, mergeObjects ); Rock.Communication.Email.Send( confirmationEmailTemplateGuid.Value, recipients, ResolveRockUrl( "~/" ), ResolveRockUrl( "~~/" ) ); } }
protected void lbSaveAccounts_Click(object sender, EventArgs e) { using (var rockContext = new RockContext()) { var txn = GetTransaction(rockContext); { decimal totalAmount = TransactionDetailsState.Select(d => d.Amount).ToList().Sum(); if (txn.TotalAmount != totalAmount) { nbError.Title = "Incorrect Amount"; nbError.Text = string.Format("<p>When updating account allocations, the total amount needs to remain the same as the original amount ({0}).</p>", txn.TotalAmount.FormatAsCurrency()); nbError.Visible = true; return; } var txnDetailService = new FinancialScheduledTransactionDetailService(rockContext); var accountService = new FinancialAccountService(rockContext); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where(a => a.ScheduledTransactionId.Equals(txn.Id)).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select(d => d.Guid).Contains(txnDetail.Guid) select txnDetail; bool accountChanges = deletedDetails.Any(); deletedDetails.ToList().ForEach(txnDetail => { txnDetailService.Delete(txnDetail); }); var changeSummary = new StringBuilder(); // Save Transaction Details foreach (var editorTxnDetail in TransactionDetailsState) { editorTxnDetail.Account = accountService.Get(editorTxnDetail.AccountId); // Add or Update the activity type var txnDetail = txn.ScheduledTransactionDetails.FirstOrDefault(d => d.Guid.Equals(editorTxnDetail.Guid)); if (txnDetail == null) { accountChanges = true; txnDetail = new FinancialScheduledTransactionDetail(); txnDetail.Guid = editorTxnDetail.Guid; txn.ScheduledTransactionDetails.Add(txnDetail); } else { if (txnDetail.AccountId != editorTxnDetail.AccountId || txnDetail.Amount != editorTxnDetail.Amount || txnDetail.Summary != editorTxnDetail.Summary) { accountChanges = true; } } changeSummary.AppendFormat("{0}: {1}", editorTxnDetail.Account != null ? editorTxnDetail.Account.Name : "?", editorTxnDetail.Amount.FormatAsCurrency()); changeSummary.AppendLine(); txnDetail.AccountId = editorTxnDetail.AccountId; txnDetail.Amount = editorTxnDetail.Amount; txnDetail.Summary = editorTxnDetail.Summary; } if (accountChanges) { // save changes rockContext.SaveChanges(); // Add a note about the change var noteType = NoteTypeCache.Read(Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid()); if (noteType != null) { var noteService = new NoteService(rockContext); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = txn.Id; note.Caption = "Updated Transaction"; note.Text = changeSummary.ToString(); noteService.Add(note); } rockContext.SaveChanges(); } ShowView(txn); } } }
/// <summary> /// Handles the Click event of the lbSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void lbSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); rockContext.WrapTransaction(() => { if (contextEntity is Person) { var personService = new PersonService(rockContext); var changes = new History.HistoryChangeList(); var _person = personService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _person.ForeignKey, tbForeignKey.Text); _person.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _person.ForeignGuid.ToString(), tbForeignGuid.Text); _person.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _person.ForeignId.ToString(), tbForeignId.Text); _person.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), _person.Id, changes); } } } else if (contextEntity is FinancialAccount) { var accountService = new FinancialAccountService(rockContext); var _account = accountService.Get(contextEntity.Id); _account.ForeignKey = tbForeignKey.Text; _account.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _account.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is FinancialBatch) { var batchService = new FinancialBatchService(rockContext); var changes = new History.HistoryChangeList(); var _batch = batchService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _batch.ForeignKey, tbForeignKey.Text); _batch.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _batch.ForeignGuid.ToString(), tbForeignGuid.Text); _batch.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _batch.ForeignId.ToString(), tbForeignId.Text); _batch.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(FinancialBatch), Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(), _batch.Id, changes); } } } else if (contextEntity is FinancialPledge) { var pledgeService = new FinancialPledgeService(rockContext); var _pledge = pledgeService.Get(contextEntity.Id); _pledge.ForeignKey = tbForeignKey.Text; _pledge.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _pledge.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is FinancialTransaction) { var transactionService = new FinancialTransactionService(rockContext); var changes = new History.HistoryChangeList(); var _transaction = transactionService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _transaction.ForeignKey, tbForeignKey.Text); _transaction.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _transaction.ForeignGuid.ToString(), tbForeignGuid.Text); _transaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _transaction.ForeignId.ToString(), tbForeignId.Text); _transaction.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(FinancialTransaction), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), _transaction.Id, changes); } } } else if (contextEntity is FinancialScheduledTransaction) { var transactionScheduledService = new FinancialScheduledTransactionService(rockContext); var _scheduledTransaction = transactionScheduledService.Get(contextEntity.Id); _scheduledTransaction.ForeignKey = tbForeignKey.Text; _scheduledTransaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _scheduledTransaction.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is Group) { var groupService = new GroupService(rockContext); var _group = groupService.Get(contextEntity.Id); _group.ForeignKey = tbForeignKey.Text; _group.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _group.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is GroupMember) { var groupMemberService = new GroupMemberService(rockContext); var changes = new History.HistoryChangeList(); var _groupMember = groupMemberService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _groupMember.ForeignKey, tbForeignKey.Text); _groupMember.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _groupMember.ForeignGuid.ToString(), tbForeignGuid.Text); _groupMember.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _groupMember.ForeignId.ToString(), tbForeignId.Text); _groupMember.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(GroupMember), Rock.SystemGuid.Category.HISTORY_PERSON_GROUP_MEMBERSHIP.AsGuid(), _groupMember.Id, changes); } } } else if (contextEntity is Metric) { var metricService = new MetricService(rockContext); var _metric = metricService.Get(contextEntity.Id); _metric.ForeignKey = tbForeignKey.Text; _metric.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _metric.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is Location) { var locationService = new LocationService(rockContext); var _location = locationService.Get(contextEntity.Id); _location.ForeignKey = tbForeignKey.Text; _location.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _location.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is PrayerRequest) { var prayerRequestService = new PrayerRequestService(rockContext); var _request = prayerRequestService.Get(contextEntity.Id); _request.ForeignKey = tbForeignKey.Text; _request.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _request.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is ContentChannel) { var contentChannelService = new ContentChannelService(rockContext); var _channel = contentChannelService.Get(contextEntity.Id); _channel.ForeignKey = tbForeignKey.Text; _channel.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _channel.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is ContentChannelItem) { var contentChannelItemService = new ContentChannelItemService(rockContext); var _item = contentChannelItemService.Get(contextEntity.Id); _item.ForeignKey = tbForeignKey.Text; _item.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _item.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } }); Page.Response.Redirect(Page.Request.Url.ToString(), true); }
public HttpResponseMessage ConfigureTextToGive(int personId, [FromBody] ConfigureTextToGiveArgs args) { // Validate the person var person = Service.Get(personId); if (person == null) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.NotFound, "The person ID is not valid")); } // Load the person's saved accounts var rockContext = Service.Context as RockContext; var savedAccountService = new FinancialPersonSavedAccountService(rockContext); var personsSavedAccounts = savedAccountService.Queryable() .Include(sa => sa.PersonAlias) .Where(sa => sa.PersonAlias.PersonId == personId) .ToList(); // Loop through each saved account. Set default to false unless the args dictate that it is the default var foundDefaultAccount = false; foreach (var savedAccount in personsSavedAccounts) { if (!foundDefaultAccount && savedAccount.Id == args.FinancialPersonSavedAccountId) { savedAccount.IsDefault = true; foundDefaultAccount = true; } else { savedAccount.IsDefault = false; } } // If the args specified an account to be default but it was not found, then return an error if (args.FinancialPersonSavedAccountId.HasValue && !foundDefaultAccount) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.NotFound, "The saved account ID is not valid")); } // Validate the account if it is being set if (args.ContributionFinancialAccountId.HasValue) { var accountService = new FinancialAccountService(rockContext); var account = accountService.Get(args.ContributionFinancialAccountId.Value); if (account == null) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.NotFound, "The financial account ID is not valid")); } if (!account.IsActive) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.BadRequest, "The financial account is not active")); } if (account.IsPublic.HasValue && !account.IsPublic.Value) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.BadRequest, "The financial account is not public")); } } // Set the person's contribution account ID person.ContributionFinancialAccountId = args.ContributionFinancialAccountId; // Success rockContext.SaveChanges(); return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK)); }
/// <summary> /// Handles the Delete event of the rGridAccount 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 rGridAccount_Delete( object sender, RowEventArgs e ) { var rockContext = new RockContext(); var accountService = new FinancialAccountService( rockContext ); var account = accountService.Get( e.RowKeyId ); if ( account != null ) { string errorMessage; if ( !accountService.CanDelete( account, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } accountService.Delete( account ); rockContext.SaveChanges(); } BindGrid(); }
/// <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> /// <exception cref="System.NotImplementedException"></exception> protected void btnSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); var financialPledgeService = new FinancialPledgeService( rockContext ); var financialAccountService = new FinancialAccountService( rockContext ); var definedValueService = new DefinedValueService( rockContext ); var person = FindPerson( rockContext ); FinancialPledge financialPledge = new FinancialPledge(); financialPledge.PersonAliasId = person.PrimaryAliasId; var financialAccount = financialAccountService.Get( GetAttributeValue( "Account" ).AsGuid() ); if ( financialAccount != null ) { financialPledge.AccountId = financialAccount.Id; } financialPledge.TotalAmount = tbTotalAmount.Text.AsDecimal(); var pledgeFrequencySelection = DefinedValueCache.Read( bddlFrequency.SelectedValue.AsInteger() ); if ( pledgeFrequencySelection != null ) { financialPledge.PledgeFrequencyValueId = pledgeFrequencySelection.Id; } financialPledge.StartDate = drpDateRange.LowerValue ?? DateTime.MinValue; financialPledge.EndDate = drpDateRange.UpperValue ?? DateTime.MaxValue; if ( sender != btnConfirm ) { var duplicatePledges = financialPledgeService.Queryable() .Where( a => a.PersonAlias.PersonId == person.Id ) .Where( a => a.AccountId == financialPledge.AccountId ) .Where( a => a.StartDate == financialPledge.StartDate ) .Where( a => a.EndDate == financialPledge.EndDate ).ToList(); if ( duplicatePledges.Any() ) { pnlAddPledge.Visible = false; pnlConfirm.Visible = true; nbDuplicatePledgeWarning.Text = "The following pledges have already been entered for you:"; nbDuplicatePledgeWarning.Text += "<ul>"; foreach ( var pledge in duplicatePledges.OrderBy( a => a.StartDate ).ThenBy( a => a.Account.Name ) ) { nbDuplicatePledgeWarning.Text += string.Format( "<li>{0} {1} {2}</li>", pledge.Account, pledge.PledgeFrequencyValue, pledge.TotalAmount ); } nbDuplicatePledgeWarning.Text += "</ul>"; return; } } financialPledgeService.Add( financialPledge ); rockContext.SaveChanges(); // populate account so that Liquid can access it financialPledge.Account = financialAccount; // populate PledgeFrequencyValue so that Liquid can access it financialPledge.PledgeFrequencyValue = definedValueService.Get( financialPledge.PledgeFrequencyValueId ?? 0 ); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); mergeFields.Add( "Person", person ); mergeFields.Add( "FinancialPledge", financialPledge ); mergeFields.Add( "PledgeFrequency", pledgeFrequencySelection ); mergeFields.Add( "Account", financialAccount ); lReceipt.Text = GetAttributeValue( "ReceiptText" ).ResolveMergeFields( mergeFields ); // Resolve any dynamic url references string appRoot = ResolveRockUrl( "~/" ); string themeRoot = ResolveRockUrl( "~~/" ); lReceipt.Text = lReceipt.Text.Replace( "~~/", themeRoot ).Replace( "~/", appRoot ); // show liquid help for debug if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) ) { lReceipt.Text += mergeFields.lavaDebugInfo(); } lReceipt.Visible = true; pnlAddPledge.Visible = false; pnlConfirm.Visible = false; // if a ConfirmationEmailTemplate is configured, send an email var confirmationEmailTemplateGuid = GetAttributeValue( "ConfirmationEmailTemplate" ).AsGuidOrNull(); if ( confirmationEmailTemplateGuid.HasValue ) { var recipients = new List<Rock.Communication.RecipientData>(); // add person and the mergeObjects (same mergeobjects as receipt) recipients.Add( new Rock.Communication.RecipientData( person.Email, mergeFields ) ); Rock.Communication.Email.Send( confirmationEmailTemplateGuid.Value, recipients, ResolveRockUrl( "~/" ), ResolveRockUrl( "~~/" ) ); } }
/// <summary> /// Verify that all settings have been configured correctly. /// </summary> /// <returns>True if the block has been configured.</returns> private bool CheckSettings() { nbBlockConfigErrors.Title = string.Empty; nbBlockConfigErrors.Text = string.Empty; RockContext rockContext = new RockContext(); FinancialAccountService accountService = new FinancialAccountService(rockContext); if (accountService.Get(GetAttributeValue("Account").AsGuid()) == null) { nbBlockConfigErrors.Heading = "No Account Configured"; nbBlockConfigErrors.Text = "<p>There is currently no account configured.</p>"; return(false); } if (DefinedValueCache.Read(GetAttributeValue("Source")) == null) { nbBlockConfigErrors.Heading = "No Source"; nbBlockConfigErrors.Text = "<p>There is currently no transaction source configured.</p>"; return(false); } if (DefinedValueCache.Read(GetAttributeValue("TransactionType")) == null) { nbBlockConfigErrors.Heading = "No Transaction Type"; nbBlockConfigErrors.Text = "<p>There is currently no transaction type configured.</p>"; return(false); } // // Hide the back button if we have been passed a value in. // if (!string.IsNullOrWhiteSpace(PageParameter("Amount"))) { lbSwipeBack.Visible = false; decimal amount; if (!decimal.TryParse(PageParameter("Amount"), out amount) || amount <= 0) { nbBlockConfigErrors.Heading = "Invalid amount"; nbBlockConfigErrors.Text = "<p>An invalid amount was given.</p>"; return(false); } tbAmount.Text = amount.ToString(); } // // Get the person they have currently selected. // Guid selectedPersonGuid; if (!Guid.TryParse(PageParameter("Person"), out selectedPersonGuid)) { nbBlockConfigErrors.Heading = "No Person"; nbBlockConfigErrors.Text = "<p>A person must be passed.</p>"; return(false); } if (new PersonService(rockContext).Get(selectedPersonGuid) == null) { nbBlockConfigErrors.Heading = "No Person"; nbBlockConfigErrors.Text = "<p>A valid person must be passed.</p>"; return(false); } SelectedPersonGuid = selectedPersonGuid; return(true); }
/// <summary> /// Handles the Click event of the btnSaveAccounts 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 btnSaveAccounts_Click(object sender, EventArgs e) { using (var rockContext = new RockContext()) { var financialScheduledTransaction = GetTransaction(rockContext); decimal totalAmount = TransactionDetailsState.Select(d => d.Amount).ToList().Sum(); if (financialScheduledTransaction.TotalAmount != totalAmount) { nbError.Title = "Incorrect Amount"; nbError.Text = string.Format("<p>When updating account allocations, the total amount needs to remain the same as the original amount ({0}).</p>", financialScheduledTransaction.TotalAmount.FormatAsCurrency()); nbError.Visible = true; return; } var txnDetailService = new FinancialScheduledTransactionDetailService(rockContext); var accountService = new FinancialAccountService(rockContext); // Delete any transaction details that were removed var txnDetailsInDB = txnDetailService.Queryable().Where(a => a.ScheduledTransactionId.Equals(financialScheduledTransaction.Id)).ToList(); var deletedDetails = from txnDetail in txnDetailsInDB where !TransactionDetailsState.Select(d => d.Guid).Contains(txnDetail.Guid) select txnDetail; bool accountChanges = deletedDetails.Any(); deletedDetails.ToList().ForEach(txnDetail => { txnDetailService.Delete(txnDetail); }); // Save Transaction Details foreach (var editorTxnDetail in TransactionDetailsState) { editorTxnDetail.Account = accountService.Get(editorTxnDetail.AccountId); // Add or Update the activity type var financialTransactionDetail = financialScheduledTransaction.ScheduledTransactionDetails.FirstOrDefault(d => d.Guid.Equals(editorTxnDetail.Guid)); if (financialTransactionDetail == null) { accountChanges = true; financialTransactionDetail = new FinancialScheduledTransactionDetail(); financialTransactionDetail.Guid = editorTxnDetail.Guid; financialScheduledTransaction.ScheduledTransactionDetails.Add(financialTransactionDetail); } else { if (financialTransactionDetail.AccountId != editorTxnDetail.AccountId || financialTransactionDetail.Amount != editorTxnDetail.Amount || financialTransactionDetail.Summary != editorTxnDetail.Summary) { accountChanges = true; } } financialTransactionDetail.AccountId = editorTxnDetail.AccountId; financialTransactionDetail.Amount = editorTxnDetail.Amount; financialTransactionDetail.Summary = editorTxnDetail.Summary; } if (accountChanges) { // save changes rockContext.SaveChanges(); } ShowView(financialScheduledTransaction); } }
/// <summary> /// Gfs the settings_ display filter value. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> protected void gfSettings_DisplayFilterValue( object sender, GridFilter.DisplayFilterValueArgs e ) { switch ( e.Key ) { case "Amount": e.Value = NumberRangeEditor.FormatDelimitedValues( e.Value, "N2" ); break; case "Frequency": int definedValueId = 0; if ( int.TryParse( e.Value, out definedValueId ) ) { var definedValue = DefinedValueCache.Read( definedValueId ); if ( definedValue != null ) { e.Value = definedValue.Value; } } break; case "Created": e.Value = DateRangePicker.FormatDelimitedValues( e.Value ); break; case "Account": int accountId = 0; if ( int.TryParse( e.Value, out accountId ) ) { var service = new FinancialAccountService( new RockContext() ); var account = service.Get( accountId ); if ( account != null ) { e.Value = account.Name; } } break; case "Include Inactive": break; default: e.Value = string.Empty; break; } }
/// <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> /// <exception cref="System.NotImplementedException"></exception> protected void btnSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); var financialPledgeService = new FinancialPledgeService(rockContext); var financialAccountService = new FinancialAccountService(rockContext); var definedValueService = new DefinedValueService(rockContext); var person = FindPerson(rockContext); FinancialPledge financialPledge = new FinancialPledge(); financialPledge.PersonAliasId = person.PrimaryAliasId; financialPledge.GroupId = ddlGroup.SelectedValueAsInt(); var financialAccount = financialAccountService.Get(GetAttributeValue("Account").AsGuid()); if (financialAccount != null) { financialPledge.AccountId = financialAccount.Id; } financialPledge.TotalAmount = tbTotalAmount.Value ?? 0.0m; var pledgeFrequencySelection = DefinedValueCache.Get(ddlFrequency.SelectedValue.AsInteger()); if (pledgeFrequencySelection != null) { financialPledge.PledgeFrequencyValueId = pledgeFrequencySelection.Id; } financialPledge.StartDate = drpDateRange.LowerValue ?? DateTime.MinValue; financialPledge.EndDate = drpDateRange.UpperValue ?? DateTime.MaxValue; if (sender != btnConfirm) { var duplicatePledges = financialPledgeService.Queryable() .Where(a => a.PersonAlias.PersonId == person.Id) .Where(a => a.AccountId == financialPledge.AccountId) .Where(a => a.StartDate == financialPledge.StartDate) .Where(a => a.EndDate == financialPledge.EndDate).ToList(); if (duplicatePledges.Any()) { pnlAddPledge.Visible = false; pnlConfirm.Visible = true; nbDuplicatePledgeWarning.Text = "The following pledges have already been entered for you:"; nbDuplicatePledgeWarning.Text += "<ul>"; foreach (var pledge in duplicatePledges.OrderBy(a => a.StartDate).ThenBy(a => a.Account.Name)) { nbDuplicatePledgeWarning.Text += string.Format("<li>{0} {1} {2}</li>", pledge.Account, pledge.PledgeFrequencyValue, pledge.TotalAmount); } nbDuplicatePledgeWarning.Text += "</ul>"; return; } } if (financialPledge.IsValid) { financialPledgeService.Add(financialPledge); rockContext.SaveChanges(); // populate account so that Liquid can access it financialPledge.Account = financialAccount; // populate PledgeFrequencyValue so that Liquid can access it financialPledge.PledgeFrequencyValue = definedValueService.Get(financialPledge.PledgeFrequencyValueId ?? 0); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson); mergeFields.Add("Person", person); mergeFields.Add("FinancialPledge", financialPledge); mergeFields.Add("PledgeFrequency", pledgeFrequencySelection); mergeFields.Add("Account", financialAccount); lReceipt.Text = GetAttributeValue("ReceiptText").ResolveMergeFields(mergeFields); // Resolve any dynamic url references string appRoot = ResolveRockUrl("~/"); string themeRoot = ResolveRockUrl("~~/"); lReceipt.Text = lReceipt.Text.Replace("~~/", themeRoot).Replace("~/", appRoot); lReceipt.Visible = true; pnlAddPledge.Visible = false; pnlConfirm.Visible = false; // if a ConfirmationEmailTemplate is configured, send an email var confirmationEmailTemplateGuid = GetAttributeValue("ConfirmationEmailTemplate").AsGuidOrNull(); if (confirmationEmailTemplateGuid.HasValue) { var emailMessage = new RockEmailMessage(confirmationEmailTemplateGuid.Value); emailMessage.AddRecipient(new RockEmailMessageRecipient(person, mergeFields)); emailMessage.AppRoot = ResolveRockUrl("~/"); emailMessage.ThemeRoot = ResolveRockUrl("~~/"); emailMessage.Send(); } } else { ShowInvalidResults(financialPledge.ValidationResults); } }
/// <summary> /// Handles the filter display for each saved user value /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <exception cref="System.NotImplementedException"></exception> protected void gfTransactions_DisplayFilterValue( object sender, Rock.Web.UI.Controls.GridFilter.DisplayFilterValueArgs e ) { switch ( e.Key ) { case "Date Range": e.Value = DateRangePicker.FormatDelimitedValues( e.Value ); break; case "Amount Range": e.Value = NumberRangeEditor.FormatDelimitedValues( e.Value, "N2" ); break; case "Account": int accountId = 0; if ( int.TryParse( e.Value, out accountId ) ) { var service = new FinancialAccountService( new RockContext() ); var account = service.Get( accountId ); if ( account != null ) { e.Value = account.Name; } } break; case "Transaction Type": case "Currency Type": case "Credit Card Type": case "Source Type": int definedValueId = 0; if ( int.TryParse( e.Value, out definedValueId ) ) { var definedValue = DefinedValueCache.Read( definedValueId ); if ( definedValue != null ) { e.Value = definedValue.Value; } } break; } }