/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; var memberQuery = new GroupMemberService(context).Queryable(); IQueryable <FormattedDataValue> groupLinkQuery; if (showAsLink) { groupLinkQuery = memberQuery.Select(gm => new HtmlLinkDataValue { SourceValue = gm.Group.Name, Url = "/group/" + gm.GroupId.ToString() }); } else { groupLinkQuery = memberQuery.Select(gm => new FormattedDataValue { SourceValue = gm.Group.Name }); } var exp = SelectExpressionExtractor.Extract(groupLinkQuery, entityIdProperty, "gm"); return(exp); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; int displayOrder = this.GetAttributeValueFromSelection("DisplayOrder", selection).AsIntegerOrNull() ?? 0; var personQry = new PersonService(context).Queryable(); IQueryable <string> personLinkQuery; string basePersonUrl = System.Web.VirtualPathUtility.ToAbsolute("~/Person/"); if (showAsLink) { // return string in format: <a href='/person/{personId}'>LastName, NickName</a> if (displayOrder == 0) { personLinkQuery = personQry.Select(p => "<a href='" + basePersonUrl + p.Id.ToString() + "'>" + p.NickName + " " + p.LastName + "</a>"); } else { personLinkQuery = personQry.Select(p => "<a href='" + basePersonUrl + p.Id.ToString() + "'>" + p.LastName + ", " + p.NickName + "</a>"); } } else { if (displayOrder == 0) { personLinkQuery = personQry.Select(p => p.NickName + " " + p.LastName); } else { personLinkQuery = personQry.Select(p => p.LastName + ", " + p.NickName); } } return(SelectExpressionExtractor.Extract(personLinkQuery, entityIdProperty, "p")); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; int displayOrder = this.GetAttributeValueFromSelection("DisplayOrder", selection).AsIntegerOrNull() ?? 0; var personQry = new PersonService(context).Queryable(); IQueryable <string> personLinkQuery; if (showAsLink) { // return string in format: <a href='/person/{personId}'>LastName, NickName</a> // prepend it with <!--LastName, NickName--> so that Sorting Works as expected if (displayOrder == 0) { personLinkQuery = personQry.Select(p => "<!--" + p.NickName + " " + p.LastName + "--><a href='/person/" + p.Id.ToString() + "'>" + p.NickName + " " + p.LastName + "</a>"); } else { personLinkQuery = personQry.Select(p => "<!--" + p.LastName + ", " + p.NickName + "--><a href='/person/" + p.Id.ToString() + "'>" + p.LastName + ", " + p.NickName + "</a>"); } } else { if (displayOrder == 0) { personLinkQuery = personQry.Select(p => p.NickName + " " + p.LastName); } else { personLinkQuery = personQry.Select(p => p.LastName + ", " + p.NickName); } } return(SelectExpressionExtractor.Extract <Rock.Model.Person>(personLinkQuery, entityIdProperty, "p")); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { var service = new GroupMemberService(context); var query = service.Queryable() .Select(gm => gm.GroupMemberStatus.ToString()); var exp = SelectExpressionExtractor.Extract(query, entityIdProperty, "gm"); return(exp); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { var memberQuery = new GroupMemberService(context).Queryable(); IQueryable <string> groupLinkQuery; groupLinkQuery = memberQuery.Select(gm => gm.Group.Campus.Name); var exp = SelectExpressionExtractor.Extract(groupLinkQuery, entityIdProperty, "gm"); return(exp); }
private void RunJob(string JobGuid, Data.RockContext context) { // Check to see if there is a valid service job var job = new Model.ServiceJobService(context).Get(JobGuid.AsGuid()); if (job != null) { // Run the job on another thread var transaction = new Transactions.RunJobNowTransaction(job.Id); System.Threading.Tasks.Task.Run(() => transaction.Execute()); } }
/// <inheritdoc/> public FinancialTransaction FetchPaymentTokenTransaction(Data.RockContext rockContext, FinancialGateway financialGateway, int?fundId, string paymentToken) { var tokenComponents = paymentToken.ToStringSafe().Split(':'); decimal amount = tokenComponents.Length >= 2 ? tokenComponents[1].AsDecimalOrNull() ?? 10 : 10; return(new FinancialTransaction { TransactionCode = paymentToken, TransactionDetails = new List <FinancialTransactionDetail> { new FinancialTransactionDetail { Amount = amount } } }); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; int displayOrder = this.GetAttributeValueFromSelection("DisplayOrder", selection).AsIntegerOrNull() ?? 0; var memberQuery = new GroupMemberService(context).Queryable(); IQueryable <FormattedDataValue> personLinkQuery; if (showAsLink) { if (displayOrder == 0) { personLinkQuery = memberQuery.Select(gm => new HtmlLinkDataValue { SourceValue = gm.Person.NickName + " " + gm.Person.LastName, Url = "/person/" + gm.PersonId.ToString() }); } else { personLinkQuery = memberQuery.Select(gm => new HtmlLinkDataValue { SourceValue = gm.Person.LastName + ", " + gm.Person.NickName, Url = "/person/" + gm.PersonId.ToString() }); } } else { if (displayOrder == 0) { personLinkQuery = memberQuery.Select(gm => new FormattedDataValue { SourceValue = gm.Person.LastName + ", " + gm.Person.NickName }); } else { personLinkQuery = memberQuery.Select(gm => new FormattedDataValue { SourceValue = gm.Person.LastName + ", " + gm.Person.NickName }); } } var exp = SelectExpressionExtractor.Extract(personLinkQuery, entityIdProperty, "gm"); return(exp); }
/// <summary> /// Filters the attributes. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="items">The items.</param> /// <param name="person">The person.</param> private static void FilterAttributes(Data.RockContext rockContext, IEnumerable <Attribute.IHasAttributes> items, Rock.Model.Person person) { if (!items.Any()) { return; } var itemType = items.First().GetType(); var entityType = EntityTypeCache.Get(itemType); if (entityType == null) { // shouldn't happen return; } var entityAttributes = AttributeCache.GetByEntity(entityType.Id); // only return attributes that the person has VIEW auth to // NOTE: There are some Attributes that even Admin doesn't have VIEW auth so (For example, some of obsolete DISC attributes) foreach (var entityAttribute in entityAttributes) { foreach (var attributeId in entityAttribute.AttributeIds) { var attribute = AttributeCache.Get(attributeId); if (!attribute.IsAuthorized(Rock.Security.Authorization.VIEW, person)) { foreach (var item in items) { if (item.AttributeValues.ContainsKey(attribute.Key)) { item.AttributeValues.Remove(attribute.Key); } if (item.Attributes.ContainsKey(attribute.Key)) { item.Attributes.Remove(attribute.Key); } } } } } }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; var groupQry = new GroupService(context).Queryable(); IQueryable <string> groupLinkQry; string baseGroupUrl = System.Web.VirtualPathUtility.ToAbsolute("~/Group/"); if (showAsLink) { // return string in format: <a href='/group/{groupId}'>Name</a> groupLinkQry = groupQry.Select(p => "<a href='" + baseGroupUrl + p.Id.ToString() + "'>" + p.Name + "</a>"); } else { groupLinkQry = groupQry.Select(p => p.Name); } return(SelectExpressionExtractor.Extract(groupLinkQry, entityIdProperty, "p")); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; var memberQuery = new GroupMemberService(context).Queryable(); IQueryable <string> groupLinkQuery; if (showAsLink) { // Return a string in the format: <a href='/group/{groupId}'>Group Name</a> groupLinkQuery = memberQuery.Select(gm => "<a href='/group/" + gm.GroupId.ToString() + "'>" + gm.Group.Name + "</a>"); } else { groupLinkQuery = memberQuery.Select(gm => gm.Group.Name); } var exp = SelectExpressionExtractor.Extract(groupLinkQuery, entityIdProperty, "gm"); return(exp); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { bool showAsLink = this.GetAttributeValueFromSelection("ShowAsLink", selection).AsBooleanOrNull() ?? false; int displayOrder = this.GetAttributeValueFromSelection("DisplayOrder", selection).AsIntegerOrNull() ?? 0; var memberQuery = new GroupMemberService(context).Queryable(); IQueryable <string> personLinkQuery; if (showAsLink) { // Return a string in the format: <a href='/person/{personId}'>LastName, NickName</a> if (displayOrder == 0) { personLinkQuery = memberQuery.Select(gm => "<a href='/person/" + gm.PersonId.ToString() + "'>" + gm.Person.NickName + " " + gm.Person.LastName + "</a>"); } else { personLinkQuery = memberQuery.Select(gm => "<a href='/person/" + gm.PersonId.ToString() + "'>" + gm.Person.LastName + ", " + gm.Person.NickName + "</a>"); } } else { if (displayOrder == 0) { personLinkQuery = memberQuery.Select(gm => gm.Person.NickName + " " + gm.Person.LastName); } else { personLinkQuery = memberQuery.Select(gm => gm.Person.LastName + ", " + gm.Person.NickName); } } var exp = SelectExpressionExtractor.Extract(personLinkQuery, entityIdProperty, "gm"); return(exp); }
public PersonalDevice UpdateByMACAddress(string macAddress, string deviceIdentifier = "", string devicePlatform = "", string deviceVersion = "", int?personAliasId = null) { var rockContext = new Data.RockContext(); var service = new PersonalDeviceService(rockContext); // MAC address var personalDevice = service.GetByMACAddress(macAddress); if (personalDevice == null) { personalDevice = new PersonalDevice(); personalDevice.MACAddress = macAddress; service.Add(personalDevice); } // unique identifier if (deviceIdentifier.IsNotNullOrWhitespace()) { personalDevice.DeviceUniqueIdentifier = deviceIdentifier; } // Platform if (devicePlatform.IsNotNullOrWhitespace()) { var dt = DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.PERSONAL_DEVICE_PLATFORM.AsGuid()); DefinedValueCache dv = null; if (dt != null) { dv = dt.DefinedValues.FirstOrDefault(v => v.Value == devicePlatform); } if (dv == null) { dv = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSONAL_DEVICE_PLATFORM_OTHER.AsGuid()); } personalDevice.PlatformValueId = dv != null ? dv.Id : (int?)null; } // Version if (deviceVersion.IsNotNullOrWhitespace()) { personalDevice.DeviceVersion = deviceVersion; } // Person if (personAliasId.HasValue) { var person = new PersonAliasService(rockContext).GetPerson(personAliasId.Value); if (person != null) { if (personalDevice.PersonAlias == null || personalDevice.PersonAlias.PersonId != person.Id) { personalDevice.PersonAliasId = personAliasId.Value; } // Update any associated interaction records for the device that do not have an associated person. if (personalDevice.Id != 0) { var interactionService = new InteractionService(rockContext); foreach (var interaction in interactionService.Queryable() .Where(i => i.PersonalDeviceId == personalDevice.Id && !i.PersonAliasId.HasValue)) { interaction.PersonAliasId = personAliasId.Value; } } } } rockContext.SaveChanges(); return(GetById(personalDevice.Id)); }
public IHttpActionResult PostInteractions([FromBody] List <MobileInteractionSession> sessions, Guid?personalDeviceGuid = null) { var person = GetPerson(); var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress; using (var rockContext = new Data.RockContext()) { var interactionChannelService = new InteractionChannelService(rockContext); var interactionComponentService = new InteractionComponentService(rockContext); var interactionSessionService = new InteractionSessionService(rockContext); var interactionService = new InteractionService(rockContext); var userLoginService = new UserLoginService(rockContext); var channelMediumTypeValue = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE); var pageEntityTypeId = EntityTypeCache.Get(typeof(Model.Page)).Id; // // Check to see if we have a site and the API key is valid. // if (MobileHelper.GetCurrentApplicationSite() == null) { return(StatusCode(System.Net.HttpStatusCode.Forbidden)); } // // Get the personal device identifier if they provided it's unique identifier. // int?personalDeviceId = null; if (personalDeviceGuid.HasValue) { personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value); } rockContext.WrapTransaction(() => { foreach (var mobileSession in sessions) { var interactionGuids = mobileSession.Interactions.Select(i => i.Guid).ToList(); var existingInteractionGuids = interactionService.Queryable() .Where(i => interactionGuids.Contains(i.Guid)) .Select(i => i.Guid) .ToList(); // // Loop through all interactions that don't already exist and add each one. // foreach (var mobileInteraction in mobileSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid))) { int?interactionComponentId = null; // // Lookup the interaction channel, and create it if it doesn't exist // if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue) { var site = SiteCache.Get(mobileInteraction.AppId.Value); var page = PageCache.Get(mobileInteraction.PageGuid.Value); if (site == null || page == null) { continue; } // // Try to find an existing interaction channel. // var interactionChannelId = interactionChannelService.Queryable() .Where(a => a.ChannelTypeMediumValueId == channelMediumTypeValue.Id && a.ChannelEntityId == site.Id) .Select(a => ( int? )a.Id) .FirstOrDefault(); // // If not found, create one. // if (!interactionChannelId.HasValue) { var interactionChannel = new InteractionChannel { Name = site.Name, ChannelTypeMediumValueId = channelMediumTypeValue.Id, ChannelEntityId = site.Id, ComponentEntityTypeId = pageEntityTypeId }; interactionChannelService.Add(interactionChannel); rockContext.SaveChanges(); interactionChannelId = interactionChannel.Id; } // // Get an existing or create a new component. // var interactionComponent = interactionComponentService.GetComponentByChannelIdAndEntityId(interactionChannelId.Value, page.Id, page.InternalName); rockContext.SaveChanges(); interactionComponentId = interactionComponent.Id; } else if (mobileInteraction.ChannelId.HasValue) { var interactionChannelId = mobileInteraction.ChannelId; if (mobileInteraction.ComponentId.HasValue) { interactionComponentId = mobileInteraction.ComponentId.Value; } else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace()) { // // Get an existing or create a new component. // var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName); rockContext.SaveChanges(); interactionComponentId = interactionComponent.Id; } else { continue; } } else { continue; } // // Add the interaction // if (interactionComponentId.HasValue) { var interaction = interactionService.CreateInteraction(interactionComponentId.Value, mobileInteraction.EntityId, mobileInteraction.Operation, mobileInteraction.Summary, mobileInteraction.Data, person?.PrimaryAliasId, mobileInteraction.DateTime, mobileSession.Application, mobileSession.OperatingSystem, mobileSession.ClientType, null, ipAddress, mobileSession.Guid); interaction.Guid = mobileInteraction.Guid; interaction.PersonalDeviceId = personalDeviceId; interactionService.Add(interaction); rockContext.SaveChanges(); } } } }); } return(Ok()); }
/// <inheritdoc/> public FinancialTransaction FetchPaymentTokenTransaction(Data.RockContext rockContext, FinancialGateway financialGateway, int?fundId, string paymentToken) { // This method is not required in our implementation. throw new NotImplementedException(); }
public IHttpActionResult PostInteractions([FromBody] List <MobileInteractionSession> sessions, Guid?personalDeviceGuid = null) { var person = GetPerson(); var ipAddress = System.Web.HttpContext.Current?.Request?.UserHostAddress; using (var rockContext = new Data.RockContext()) { var interactionChannelService = new InteractionChannelService(rockContext); var interactionComponentService = new InteractionComponentService(rockContext); var interactionSessionService = new InteractionSessionService(rockContext); var interactionService = new InteractionService(rockContext); var userLoginService = new UserLoginService(rockContext); var channelMediumTypeValue = DefinedValueCache.Get(SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE); var pageEntityTypeId = EntityTypeCache.Get(typeof(Model.Page)).Id; // // Check to see if we have a site and the API key is valid. // if (MobileHelper.GetCurrentApplicationSite() == null) { return(StatusCode(System.Net.HttpStatusCode.Forbidden)); } // // Get the personal device identifier if they provided it's unique identifier. // int?personalDeviceId = null; if (personalDeviceGuid.HasValue) { personalDeviceId = new PersonalDeviceService(rockContext).GetId(personalDeviceGuid.Value); } // // Create a quick way to cache data since we have to loop twice. // var interactionComponentLookup = new Dictionary <string, int>(); // // Helper method to get a cache key for looking up the component Id. // string GetComponentCacheKey(MobileInteraction mi) { return($"{mi.AppId}:{mi.PageGuid}:{mi.ChannelGuid}:{mi.ChannelId}:{mi.ComponentId}:{mi.ComponentName}"); } // // Interactions Components will now try to load from cache which // causes problems if we are inside a transaction. So first loop through // everything and make sure all our components and channels exist. // var prePassInteractions = sessions.SelectMany(a => a.Interactions) .DistinctBy(a => GetComponentCacheKey(a)); // // It's safe to do this pre-pass outside the transaction since we are just creating // the channels and components (if necessary), which is going to have to be done at // at some point no matter what. // foreach (var mobileInteraction in prePassInteractions) { // // Lookup the interaction channel, and create it if it doesn't exist // if (mobileInteraction.AppId.HasValue && mobileInteraction.PageGuid.HasValue) { var site = SiteCache.Get(mobileInteraction.AppId.Value); var page = PageCache.Get(mobileInteraction.PageGuid.Value); if (site == null || page == null) { continue; } // // Try to find an existing interaction channel. // var interactionChannelId = InteractionChannelCache.GetChannelIdByTypeIdAndEntityId(channelMediumTypeValue.Id, site.Id, site.Name, pageEntityTypeId, null); // // Get an existing or create a new component. // var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, page.Id, page.InternalName); interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId); } else if (mobileInteraction.ChannelId.HasValue || mobileInteraction.ChannelGuid.HasValue) { int?interactionChannelId = null; if (mobileInteraction.ChannelId.HasValue) { interactionChannelId = mobileInteraction.ChannelId.Value; } else if (mobileInteraction.ChannelGuid.HasValue) { interactionChannelId = InteractionChannelCache.Get(mobileInteraction.ChannelGuid.Value)?.Id; } if (interactionChannelId.HasValue) { if (mobileInteraction.ComponentId.HasValue) { // Use the provided component identifier. interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), mobileInteraction.ComponentId.Value); } else if (mobileInteraction.ComponentName.IsNotNullOrWhiteSpace()) { int interactionComponentId; // Get or create a new component with the details we have. if (mobileInteraction.ComponentEntityId.HasValue) { interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId.Value, mobileInteraction.ComponentEntityId, mobileInteraction.ComponentName); } else { var interactionComponent = interactionComponentService.GetComponentByComponentName(interactionChannelId.Value, mobileInteraction.ComponentName); rockContext.SaveChanges(); interactionComponentId = interactionComponent.Id; } interactionComponentLookup.AddOrReplace(GetComponentCacheKey(mobileInteraction), interactionComponentId); } } } } // // Now wrap the actual interaction creation inside a transaction. We should // probably move this so it uses the InteractionTransaction class for better // performance. This is so we can inform the client that either everything // saved or that nothing saved. No partial saves here. // rockContext.WrapTransaction(() => { foreach (var mobileSession in sessions) { var interactionGuids = mobileSession.Interactions.Select(i => i.Guid).ToList(); var existingInteractionGuids = interactionService.Queryable() .Where(i => interactionGuids.Contains(i.Guid)) .Select(i => i.Guid) .ToList(); // // Loop through all interactions that don't already exist and add each one. // foreach (var mobileInteraction in mobileSession.Interactions.Where(i => !existingInteractionGuids.Contains(i.Guid))) { string cacheKey = GetComponentCacheKey(mobileInteraction); if (!interactionComponentLookup.ContainsKey(cacheKey)) { // Shouldn't happen, but just in case. continue; } var interactionComponentId = interactionComponentLookup[cacheKey]; // // Add the interaction // var interaction = interactionService.CreateInteraction(interactionComponentId, mobileInteraction.EntityId, mobileInteraction.Operation, mobileInteraction.Summary, mobileInteraction.Data, person?.PrimaryAliasId, RockDateTime.ConvertLocalDateTimeToRockDateTime(mobileInteraction.DateTime.LocalDateTime), mobileSession.Application, mobileSession.OperatingSystem, mobileSession.ClientType, null, ipAddress, mobileSession.Guid); interaction.Guid = mobileInteraction.Guid; interaction.PersonalDeviceId = personalDeviceId; interaction.RelatedEntityTypeId = mobileInteraction.RelatedEntityTypeId; interaction.RelatedEntityId = mobileInteraction.RelatedEntityId; interaction.ChannelCustom1 = mobileInteraction.ChannelCustom1; interaction.ChannelCustom2 = mobileInteraction.ChannelCustom2; interaction.ChannelCustomIndexed1 = mobileInteraction.ChannelCustomIndexed1; interactionService.Add(interaction); // Attempt to process this as a communication interaction. ProcessCommunicationInteraction(mobileSession, mobileInteraction, rockContext); } } rockContext.SaveChanges(); }); } return(Ok()); }
/// <summary> /// Get the current site as specified by the X-Rock-App-Id header and optionally /// validate the X-Rock-Mobile-Api-Key against that site. /// </summary> /// <param name="validateApiKey"><c>true</c> if the X-Rock-Mobile-Api-Key header should be validated.</param> /// <param name="rockContext">The Rock context to use when accessing the database.</param> /// <returns>A SiteCache object or null if the request was not valid.</returns> public static SiteCache GetCurrentApplicationSite(bool validateApiKey = true, Data.RockContext rockContext = null) { var appId = HttpContext.Current?.Request?.Headers?["X-Rock-App-Id"]; if (!appId.AsIntegerOrNull().HasValue) { return(null); } // // Lookup the site from the App Id. // var site = SiteCache.Get(appId.AsInteger()); if (site == null) { return(null); } // // If we have been requested to validate the Api Key then do so. // if (validateApiKey) { var requestApiKey = System.Web.HttpContext.Current?.Request?.Headers?["X-Rock-Mobile-Api-Key"]; if (GetMobileApplicationUser(site, requestApiKey) != null) { return(site); } else { return(null); } } else { return(site); } }
public object UpdateProfile(MobilePerson profile) { var user = UserLoginService.GetCurrentUser(false); if (user == null) { return(ActionStatusCode(System.Net.HttpStatusCode.Unauthorized)); } var personId = user.PersonId.Value; var rockContext = new Data.RockContext(); var personService = new PersonService(rockContext); var phoneNumberService = new PhoneNumberService(rockContext); var person = personService.Get(personId); person.NickName = person.NickName == person.FirstName ? profile.FirstName : person.NickName; person.FirstName = profile.FirstName; person.LastName = profile.LastName; var gender = (Model.Gender)profile.Gender; if (GenderVisibility != VisibilityTriState.Hidden) { person.Gender = gender; } if (GetAttributeValue(AttributeKeys.BirthDateShow).AsBoolean()) { person.SetBirthDate(profile.BirthDate?.Date); } if (GetAttributeValue(AttributeKeys.CampusShow).AsBoolean()) { person.PrimaryFamily.CampusId = profile.CampusGuid.HasValue ? CampusCache.Get(profile.CampusGuid.Value)?.Id : null; } if (GetAttributeValue(AttributeKeys.EmailShow).AsBoolean()) { person.Email = profile.Email; } if (GetAttributeValue(AttributeKeys.MobilePhoneShow).AsBoolean()) { int phoneNumberTypeId = DefinedValueCache.Get(SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE).Id; var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId == phoneNumberTypeId); if (phoneNumber == null) { phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId }; person.PhoneNumbers.Add(phoneNumber); } // TODO: What to do with country code? phoneNumber.CountryCode = PhoneNumber.CleanNumber("+1"); phoneNumber.Number = PhoneNumber.CleanNumber(profile.MobilePhone); if (string.IsNullOrWhiteSpace(phoneNumber.Number)) { person.PhoneNumbers.Remove(phoneNumber); phoneNumberService.Delete(phoneNumber); } } if (GetAttributeValue(AttributeKeys.AddressShow).AsBoolean()) { var addressTypeGuid = SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid(); var groupLocationService = new GroupLocationService(rockContext); var dvHomeAddressType = DefinedValueCache.Get(addressTypeGuid); var familyAddress = groupLocationService.Queryable().Where(l => l.GroupId == person.PrimaryFamily.Id && l.GroupLocationTypeValueId == dvHomeAddressType.Id).FirstOrDefault(); if (familyAddress != null && string.IsNullOrWhiteSpace(profile.HomeAddress.Street1)) { // delete the current address groupLocationService.Delete(familyAddress); } else { if (!string.IsNullOrWhiteSpace(profile.HomeAddress.Street1)) { if (familyAddress == null) { familyAddress = new GroupLocation(); groupLocationService.Add(familyAddress); familyAddress.GroupLocationTypeValueId = dvHomeAddressType.Id; familyAddress.GroupId = person.PrimaryFamily.Id; familyAddress.IsMailingLocation = true; familyAddress.IsMappedLocation = true; } else if (familyAddress.Location.Street1 != profile.HomeAddress.Street1) { // user clicked move so create a previous address var previousAddress = new GroupLocation(); groupLocationService.Add(previousAddress); var previousAddressValue = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_PREVIOUS.AsGuid()); if (previousAddressValue != null) { previousAddress.GroupLocationTypeValueId = previousAddressValue.Id; previousAddress.GroupId = person.PrimaryFamily.Id; Location previousAddressLocation = new Location { Street1 = familyAddress.Location.Street1, Street2 = familyAddress.Location.Street2, City = familyAddress.Location.City, State = familyAddress.Location.State, PostalCode = familyAddress.Location.PostalCode, Country = familyAddress.Location.Country }; previousAddress.Location = previousAddressLocation; } } // TODO: ??? // familyAddress.IsMailingLocation = cbIsMailingAddress.Checked; // familyAddress.IsMappedLocation = cbIsPhysicalAddress.Checked; familyAddress.Location = new LocationService(rockContext).Get( profile.HomeAddress.Street1, string.Empty, profile.HomeAddress.City, profile.HomeAddress.State, profile.HomeAddress.PostalCode, profile.HomeAddress.Country, person.PrimaryFamily, true); // since there can only be one mapped location, set the other locations to not mapped if (familyAddress.IsMappedLocation) { var groupLocations = groupLocationService.Queryable() .Where(l => l.GroupId == person.PrimaryFamily.Id && l.Id != familyAddress.Id).ToList(); foreach (var groupLocation in groupLocations) { groupLocation.IsMappedLocation = false; } } rockContext.SaveChanges(); } } } rockContext.SaveChanges(); var mobilePerson = MobileHelper.GetMobilePerson(person, MobileHelper.GetCurrentApplicationSite()); mobilePerson.AuthToken = MobileHelper.GetAuthenticationToken(user.UserName); return(ActionOk(mobilePerson)); }
/// <summary> /// Handles a recieved message /// </summary> /// <param name="toPhone">To phone.</param> /// <param name="fromPhone">From phone.</param> /// <param name="message">The message.</param> /// <param name="response">The response.</param> public static void MessageRecieved(string toPhone, string fromPhone, string message, out string response) { response = string.Empty; bool foundWorkflow = false; // get TextToWorkflow defined types for this number var definedType = DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.TEXT_TO_WORKFLOW.AsGuid()); if (definedType != null && definedType.DefinedValues != null && definedType.DefinedValues.Any()) { var smsWorkflows = definedType.DefinedValues.Where(v => v.Value.AsNumeric() == toPhone.AsNumeric()).OrderBy(v => v.Order).ToList(); // iterate through workflows looking for a keyword match foreach (DefinedValueCache dvWorkflow in smsWorkflows) { string keywordExpression = dvWorkflow.GetAttributeValue("KeywordExpression"); string workflowAttributes = dvWorkflow.GetAttributeValue("WorkflowAttributes"); string nameTemplate = dvWorkflow.GetAttributeValue("WorkflowNameTemplate"); // if not keyword expression add wildcard expression if (string.IsNullOrWhiteSpace(keywordExpression)) { keywordExpression = ".*"; } // if the keyword is just a * then replace it if (keywordExpression == "*") { keywordExpression = ".*"; } // Prefix keyword with start-of-string assertion (input needs to start with selected expression) if (!keywordExpression.StartsWith("^")) { keywordExpression = $"^{keywordExpression}"; } if (!string.IsNullOrWhiteSpace(keywordExpression)) { Match match = Regex.Match(message, keywordExpression, RegexOptions.IgnoreCase); if (match.Success) { foundWorkflow = true; var workflowTypeGuid = dvWorkflow.GetAttributeValue("WorkflowType").AsGuidOrNull(); if (workflowTypeGuid.HasValue) { // launch workflow using (var rockContext = new Data.RockContext()) { var personService = new PersonService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var workflowType = WorkflowTypeCache.Read(workflowTypeGuid.Value); if (workflowType != null) { // Activate a new workflow var workflow = Rock.Model.Workflow.Activate(workflowType, "Request from " + (fromPhone ?? "??"), rockContext); // give preference to people with the phone in the mobile phone type // first look for a person with the phone number as a mobile phone order by family role then age var mobilePhoneType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE); var familyGroupType = GroupTypeCache.Read(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY); // Get all people phone number var peopleWithMobileNumber = personService.Queryable() .Where(p => p.PhoneNumbers.Any(n => (n.CountryCode + n.Number) == fromPhone.Replace("+", "") && n.NumberTypeValueId == mobilePhoneType.Id) ) .Select(p => p.Id); // Find first person ordered by role (adult first), then by birthdate (oldest first) var fromPerson = groupMemberService.Queryable() .Where(m => m.Group.GroupTypeId == familyGroupType.Id && peopleWithMobileNumber.Contains(m.PersonId)) .OrderBy(m => m.GroupRole.Order) .ThenBy(m => m.Person.BirthDate ?? DateTime.MinValue) .Select(m => m.Person) .FirstOrDefault(); // if no match then look for the phone in any phone type ordered by family role then age if (fromPerson == null) { var peopleWithAnyNumber = personService.Queryable() .Where(p => p.PhoneNumbers.Any(n => (n.CountryCode + n.Number) == fromPhone.Replace("+", "") && n.NumberTypeValueId == mobilePhoneType.Id) ) .Select(p => p.Id); fromPerson = groupMemberService.Queryable() .Where(m => m.Group.GroupTypeId == familyGroupType.Id && peopleWithMobileNumber.Contains(m.PersonId)) .OrderBy(m => m.GroupRole.Order) .ThenBy(m => m.Person.BirthDate ?? DateTime.MinValue) .Select(m => m.Person).FirstOrDefault(); } // Set initiator if (fromPerson != null) { workflow.InitiatorPersonAliasId = fromPerson.PrimaryAliasId; } // create merge object var formattedPhoneNumber = PhoneNumber.CleanNumber(PhoneNumber.FormattedNumber(PhoneNumber.DefaultCountryCode(), fromPhone)); List <string> matchGroups = new List <string>(); foreach (var matchItem in match.Groups) { matchGroups.Add(matchItem.ToString()); } Dictionary <string, object> mergeValues = new Dictionary <string, object>(); mergeValues.Add("FromPhone", formattedPhoneNumber); mergeValues.Add("ToPhone", toPhone); mergeValues.Add("MessageBody", message); mergeValues.Add("MatchedGroups", matchGroups); mergeValues.Add("ReceivedTime", RockDateTime.Now.ToString("HH:mm:ss")); mergeValues.Add("ReceivedDate", RockDateTime.Now.ToShortDateString()); mergeValues.Add("ReceivedDateTime", RockDateTime.Now.ToString("o")); mergeValues.Add("FromPerson", fromPerson); // add phone number attribute workflow.SetAttributeValue("FromPhone", fromPhone); // set workflow attributes string[] attributes = workflowAttributes.Split('|'); foreach (string attribute in attributes) { if (attribute.Contains('^')) { string[] settings = attribute.Split('^'); workflow.SetAttributeValue(settings[0], settings[1].ResolveMergeFields(mergeValues)); } } // set workflow name string name = nameTemplate.ResolveMergeFields(mergeValues); if (name.IsNotNullOrWhitespace()) { workflow.Name = name; } // process the workflow List <string> workflowErrors; new Rock.Model.WorkflowService(rockContext).Process(workflow, out workflowErrors); // check to see if there is a response to return string responseAttribute = workflow.GetAttributeValue("SMSResponse"); if (responseAttribute != null && !string.IsNullOrWhiteSpace(responseAttribute)) { response = responseAttribute; } } else { response = "This keyword is no longer valid."; } } } else { response = "No response could be provided for this keyword."; } // once we find one match stop processing break; } } } if (!foundWorkflow) { response = "The keyword you provided was not valid. "; } } }
/// <summary> /// Get the current site as specified by the X-Rock-App-Id header and optionally /// validate the X-Rock-Mobile-Api-Key against that site. /// </summary> /// <param name="validateApiKey"><c>true</c> if the X-Rock-Mobile-Api-Key header should be validated.</param> /// <param name="rockContext">The Rock context to use when accessing the database.</param> /// <returns>A SiteCache object or null if the request was not valid.</returns> public static SiteCache GetCurrentApplicationSite(bool validateApiKey = true, Data.RockContext rockContext = null) { var appId = HttpContext.Current?.Request?.Headers?["X-Rock-App-Id"]; if (!appId.AsIntegerOrNull().HasValue) { return(null); } // // Lookup the site from the App Id. // var site = SiteCache.Get(appId.AsInteger()); if (site == null) { return(null); } // // If we have been requested to validate the Api Key then do so. // if (validateApiKey) { var appApiKey = System.Web.HttpContext.Current?.Request?.Headers?["X-Rock-Mobile-Api-Key"]; var additionalSettings = site.AdditionalSettings.FromJsonOrNull <AdditionalSiteSettings>(); // // Ensure we have valid site configuration. // if (additionalSettings == null || !additionalSettings.ApiKeyId.HasValue) { return(null); } rockContext = rockContext ?? new Data.RockContext(); var userLogin = new UserLoginService(rockContext).GetByApiKey(appApiKey).FirstOrDefault(); if (userLogin != null && userLogin.Id == additionalSettings.ApiKeyId) { return(site); } else { return(null); } } else { return(site); } }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { string[] selectionValues = selection.Split('|'); if (selectionValues.Length < 4) { return(null); } /* 2020-05-19 MDP * The TotalAmount Comparison logic is that the displayed TotalAmount will show blank if the criteria doesn't match * For example: * Total Amount >= $100.00 * If a person's total giving is $100.01, $100.01 will be displayed as the total giving in the report * If the person's total giving is $99.99, the total giving in the report will just show blank * * * This display logic is done in the GetGridField method */ DateRange dateRange; if (selectionValues.Length >= 7) { string slidingDelimitedValues = selectionValues[6].Replace(',', '|'); dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(slidingDelimitedValues); } else { // if converting from a previous version of the selection DateTime?startDate = selectionValues[2].AsDateTime(); DateTime?endDate = selectionValues[3].AsDateTime(); dateRange = new DateRange(startDate, endDate); if (dateRange.End.HasValue) { // the DateRange picker doesn't automatically add a full day to the end date dateRange.End.Value.AddDays(1); } } var accountIdList = new List <int>(); if (selectionValues.Length >= 5) { var accountGuids = selectionValues[4].Split(',').Select(a => a.AsGuid()).Where(a => a != Guid.Empty).ToList(); accountIdList = new FinancialAccountService(context).GetByGuids(accountGuids).Select(a => a.Id).ToList(); } bool combineGiving = false; if (selectionValues.Length >= 6) { combineGiving = selectionValues[5].AsBooleanOrNull() ?? false; } bool useAnalytics = false; if (selectionValues.Length >= 8) { useAnalytics = selectionValues[7].AsBooleanOrNull() ?? false; } int transactionTypeContributionId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()).Id; IQueryable <decimal> personTotalAmountQry; if (useAnalytics) { /* 2020-05-20 MDP * Analytics tables don't have a reference between a transaction and it's refund (unless we join the analytics tables to the TransactionRefund table). * That isn't a problem unless the refund for a transaction is later than the specified date range. * We discussed this and decided to not worry abou the late refund problem right now. * * Also, the total giving will be correct even when factoring in refunds * because the Analytics tables will have a negative amount for refund transactions * */ var analyticsFinancialTransactionQry = new AnalyticsSourceFinancialTransactionService(context).Queryable() .Where(xx => xx.TransactionTypeValueId == transactionTypeContributionId) .Where(xx => xx.AuthorizedPersonAliasId.HasValue); if (dateRange.Start.HasValue) { analyticsFinancialTransactionQry = analyticsFinancialTransactionQry.Where(xx => xx.TransactionDateTime >= dateRange.Start.Value); } if (dateRange.End.HasValue) { analyticsFinancialTransactionQry = analyticsFinancialTransactionQry.Where(xx => xx.TransactionDateTime < dateRange.End.Value); } bool limitToAccounts = accountIdList.Any(); if (limitToAccounts) { analyticsFinancialTransactionQry = analyticsFinancialTransactionQry.Where(xx => xx.AccountId.HasValue && accountIdList.Contains(xx.AccountId.Value)); } if (combineGiving) { var analyticsPersonAmountQry = new AnalyticsDimPersonCurrentService(context).Queryable() .Join(analyticsFinancialTransactionQry, p => p.GivingId, f => f.GivingId, (p, f) => new { p.PersonId, f.Amount }); personTotalAmountQry = new PersonService(context).Queryable() .Select(p => analyticsPersonAmountQry .Where(ww => ww.PersonId == p.Id) .Sum(ww => ww.Amount)); } else { var analyticsPersonAmountQry = new AnalyticsDimPersonCurrentService(context).Queryable() .Join(analyticsFinancialTransactionQry, p => p.Id, f => f.AuthorizedPersonKey, (p, f) => new { p.PersonId, f.Amount }); personTotalAmountQry = new PersonService(context).Queryable() .Select(p => analyticsPersonAmountQry .Where(ww => ww.PersonId == p.Id) .Sum(ww => ww.Amount)); } } else { var financialTransactionQry = new FinancialTransactionDetailService(context).Queryable() .Where(xx => xx.Transaction.TransactionTypeValueId == transactionTypeContributionId) .Where(xx => xx.Transaction.AuthorizedPersonAliasId.HasValue); if (dateRange.Start.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime >= dateRange.Start.Value); } if (dateRange.End.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime < dateRange.End.Value); } bool limitToAccounts = accountIdList.Any(); if (limitToAccounts) { financialTransactionQry = financialTransactionQry.Where(xx => accountIdList.Contains(xx.AccountId)); } // exclude the financial transactions that were used for refunds. // This is because we'll get the refund transactions of each non-refund transaction when getting the total amount var refundsQry = new FinancialTransactionRefundService(context).Queryable(); financialTransactionQry = financialTransactionQry.Where(xx => !refundsQry.Any(r => r.Id == xx.TransactionId)); /* 2020-05-02 MDP * To factor in Refunds, subtract (but actually add since the amount will be negative) * the refund amount if there is a refund associated with that transaction. * * Also, don't apply a date filter on the refund since we want to factor in refunds * that might have occurred after the date range * * The Linq is written in a way to avoid the RefundAmount getting queried twice (once if it is null and another if it not null) */ if (combineGiving) { personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry.Where(ww => p.GivingId == ww.Transaction.AuthorizedPersonAlias.Person.GivingId ) .Select(x => new { x.Amount, RefundAmount = (x.Transaction.RefundDetails.FinancialTransaction .TransactionDetails .Where(r => r.AccountId == x.AccountId) .Sum(r => ( decimal? )r.Amount) ) }) .Sum ( aa => aa.Amount + (aa.RefundAmount ?? 0.00M) ) ); } else { personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry.Where(ww => ww.Transaction.AuthorizedPersonAlias.PersonId == p.Id ) .Select(x => new { x.Amount, RefundAmount = (x.Transaction.RefundDetails.FinancialTransaction .TransactionDetails .Where(r => r.AccountId == x.AccountId) .Sum(r => ( decimal? )r.Amount) ) }) .Sum ( aa => aa.Amount + (aa.RefundAmount ?? 0.00M) ) ); } } var selectExpression = SelectExpressionExtractor.Extract(personTotalAmountQry, entityIdProperty, "p"); return(selectExpression); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { string[] selectionValues = selection.Split('|'); if (selectionValues.Length < 4) { return(null); } ComparisonType comparisonType = selectionValues[0].ConvertToEnum <ComparisonType>(ComparisonType.GreaterThanOrEqualTo); decimal amount = selectionValues[1].AsDecimalOrNull() ?? 0.00M; DateRange dateRange; if (selectionValues.Length >= 7) { string slidingDelimitedValues = selectionValues[6].Replace(',', '|'); dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(slidingDelimitedValues); } else { // if converting from a previous version of the selection DateTime?startDate = selectionValues[2].AsDateTime(); DateTime?endDate = selectionValues[3].AsDateTime(); dateRange = new DateRange(startDate, endDate); if (dateRange.End.HasValue) { // the DateRange picker doesn't automatically add a full day to the end date dateRange.End.Value.AddDays(1); } } var accountIdList = new List <int>(); if (selectionValues.Length >= 5) { var accountGuids = selectionValues[4].Split(',').Select(a => a.AsGuid()).ToList(); accountIdList = new FinancialAccountService(context).GetByGuids(accountGuids).Select(a => a.Id).ToList(); } bool combineGiving = false; if (selectionValues.Length >= 6) { combineGiving = selectionValues[5].AsBooleanOrNull() ?? false; } bool useAnalytics = false; if (selectionValues.Length >= 8) { useAnalytics = selectionValues[7].AsBooleanOrNull() ?? false; } int transactionTypeContributionId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()).Id; IQueryable <decimal> personTotalAmountQry; if (useAnalytics) { var financialTransactionQry = new AnalyticsSourceFinancialTransactionService(context).Queryable() .Where(xx => xx.TransactionTypeValueId == transactionTypeContributionId) .Where(xx => xx.AuthorizedPersonAliasId.HasValue); if (dateRange.Start.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.TransactionDateTime >= dateRange.Start.Value); } if (dateRange.End.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.TransactionDateTime < dateRange.End.Value); } bool limitToAccounts = accountIdList.Any(); if (limitToAccounts) { financialTransactionQry = financialTransactionQry.Where(xx => xx.AccountId.HasValue && accountIdList.Contains(xx.AccountId.Value)); } if (comparisonType == ComparisonType.LessThan) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount < amount); } else if (comparisonType == ComparisonType.EqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount == amount); } else if (comparisonType == ComparisonType.GreaterThanOrEqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount >= amount); } if (combineGiving) { var personAmount = new AnalyticsDimPersonCurrentService(context).Queryable() .Join(financialTransactionQry, p => p.GivingId, f => f.GivingId, (p, f) => new { p.PersonId, f.Amount }); personTotalAmountQry = new PersonService(context).Queryable() .Select(p => personAmount .Where(ww => ww.PersonId == p.Id) .Sum(ww => ww.Amount)); } else { var personAmount = new AnalyticsDimPersonCurrentService(context).Queryable() .Join(financialTransactionQry, p => p.Id, f => f.AuthorizedPersonKey, (p, f) => new { p.PersonId, f.Amount }); personTotalAmountQry = new PersonService(context).Queryable() .Select(p => personAmount .Where(ww => ww.PersonId == p.Id) .Sum(ww => ww.Amount)); } } else { var financialTransactionQry = new FinancialTransactionDetailService(context).Queryable() .Where(xx => xx.Transaction.TransactionTypeValueId == transactionTypeContributionId) .Where(xx => xx.Transaction.AuthorizedPersonAliasId.HasValue); if (dateRange.Start.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime >= dateRange.Start.Value); } if (dateRange.End.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime < dateRange.End.Value); } bool limitToAccounts = accountIdList.Any(); if (limitToAccounts) { financialTransactionQry = financialTransactionQry.Where(xx => accountIdList.Contains(xx.AccountId)); } if (comparisonType == ComparisonType.LessThan) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount < amount); } else if (comparisonType == ComparisonType.EqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount == amount); } else if (comparisonType == ComparisonType.GreaterThanOrEqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount >= amount); } if (combineGiving) { //// if combineGiving.. // if they aren't in a giving group, sum up transactions amounts by the person // if they are in a giving group, sum up transactions amounts by the persons that are in the person's giving group personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry .Where(ww => (!p.GivingGroupId.HasValue && ww.Transaction.AuthorizedPersonAlias.PersonId == p.Id) || (p.GivingGroupId.HasValue && ww.Transaction.AuthorizedPersonAlias.Person.GivingGroupId == p.GivingGroupId)) .Sum(aa => aa.Amount)); } else { personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry .Where(ww => ww.Transaction.AuthorizedPersonAlias.PersonId == p.Id) .Sum(aa => aa.Amount)); } } var selectExpression = SelectExpressionExtractor.Extract(personTotalAmountQry, entityIdProperty, "p"); return(selectExpression); }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override System.Linq.Expressions.Expression GetExpression(Data.RockContext context, System.Linq.Expressions.MemberExpression entityIdProperty, string selection) { string[] selectionValues = selection.Split('|'); if (selectionValues.Length < 4) { return(null); } ComparisonType comparisonType = selectionValues[0].ConvertToEnum <ComparisonType>(ComparisonType.GreaterThanOrEqualTo); decimal amount = selectionValues[1].AsDecimalOrNull() ?? 0.00M; DateTime? startDate = selectionValues[2].AsDateTime(); DateTime? endDate = selectionValues[3].AsDateTime(); var accountIdList = new List <int>(); if (selectionValues.Length >= 5) { var accountGuids = selectionValues[4].Split(',').Select(a => a.AsGuid()).ToList(); accountIdList = new FinancialAccountService(context).GetByGuids(accountGuids).Select(a => a.Id).ToList(); } bool combineGiving = false; if (selectionValues.Length >= 6) { combineGiving = selectionValues[5].AsBooleanOrNull() ?? false; } int transactionTypeContributionId = Rock.Web.Cache.DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()).Id; var financialTransactionQry = new FinancialTransactionDetailService(context).Queryable() .Where(xx => xx.Transaction.TransactionTypeValueId == transactionTypeContributionId) .Where(xx => xx.Transaction.AuthorizedPersonAliasId.HasValue); if (startDate.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime >= startDate.Value); } if (endDate.HasValue) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Transaction.TransactionDateTime < endDate.Value); } bool limitToAccounts = accountIdList.Any(); if (limitToAccounts) { financialTransactionQry = financialTransactionQry.Where(xx => accountIdList.Contains(xx.AccountId)); } if (comparisonType == ComparisonType.LessThan) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount < amount); } else if (comparisonType == ComparisonType.EqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount == amount); } else if (comparisonType == ComparisonType.GreaterThanOrEqualTo) { financialTransactionQry = financialTransactionQry.Where(xx => xx.Amount >= amount); } IQueryable <decimal> personTotalAmountQry; if (combineGiving) { //// if combineGiving.. // if they aren't in a giving group, sum up transactions amounts by the person // if they are in a giving group, sum up transactions amounts by the persons that are in the person's giving group personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry .Where(ww => (!p.GivingGroupId.HasValue && ww.Transaction.AuthorizedPersonAlias.PersonId == p.Id) || (p.GivingGroupId.HasValue && ww.Transaction.AuthorizedPersonAlias.Person.GivingGroupId == p.GivingGroupId)) .Sum(aa => aa.Amount)); } else { personTotalAmountQry = new PersonService(context).Queryable() .Select(p => financialTransactionQry .Where(ww => ww.Transaction.AuthorizedPersonAlias.PersonId == p.Id) .Sum(aa => aa.Amount)); } var selectExpression = SelectExpressionExtractor.Extract(personTotalAmountQry, entityIdProperty, "p"); return(selectExpression); }