Esempio n. 1
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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"));
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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"));
        }
Esempio n. 4
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }
Esempio n. 5
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }
Esempio n. 6
0
        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
                    }
                }
            });
        }
Esempio n. 8
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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"));
        }
Esempio n. 11
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }
Esempio n. 12
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }
Esempio n. 13
0
        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));
        }
Esempio n. 14
0
        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());
        }
Esempio n. 15
0
 /// <inheritdoc/>
 public FinancialTransaction FetchPaymentTokenTransaction(Data.RockContext rockContext, FinancialGateway financialGateway, int?fundId, string paymentToken)
 {
     // This method is not required in our implementation.
     throw new NotImplementedException();
 }
Esempio n. 16
0
        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());
        }
Esempio n. 17
0
        /// <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);
            }
        }
Esempio n. 18
0
        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));
        }
Esempio n. 19
0
        /// <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. ";
                }
            }
        }
Esempio n. 20
0
        /// <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);
        }
Esempio n. 22
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override 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);
        }