Пример #1
0
        /// <summary>
        /// Finds any missing personal link section orders
        /// and <see cref="Rock.Data.Service{T}.Add(T)">adds</see> them  (but doesn't .SaveChanges)
        /// If this returns true, call SaveChanges to save them to the database.
        /// </summary>
        /// <param name="currentPerson">The current person.</param>
        /// <returns>List&lt;PersonalLinkSectionOrder&gt;.</returns>
        public bool AddMissingPersonalLinkSectionOrders(Person currentPerson)
        {
            var primaryAliasId = currentPerson.PrimaryAliasId;

            if (!primaryAliasId.HasValue)
            {
                // shouldn't happen, but just in case
                return(false);
            }

            var rockContext = this.Context as RockContext;

            var personalLinkSectionService = new PersonalLinkSectionService(rockContext);

            var personAliasQuery          = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == currentPerson.Id);
            var personalLinkSectionsQuery = personalLinkSectionService
                                            .Queryable()
                                            .Where(a =>
                                                   a.IsShared ||
                                                   (a.PersonAliasId.HasValue && personAliasQuery.Any(aa => aa.Id == a.PersonAliasId.Value)));

            var missingSectionOrders = personalLinkSectionsQuery
                                       .Where(a => !a.PersonalLinkSectionOrders.Any(xx => personAliasQuery.Any(pa => pa.Id == xx.PersonAliasId)))
                                       .ToList()
                                       .OrderBy(a => a.Name)
                                       .Select(a => new PersonalLinkSectionOrder
            {
                PersonAliasId = primaryAliasId.Value,
                SectionId     = a.Id,
                Order         = 0
            }).ToList();

            if (missingSectionOrders.Any())
            {
                // add the new order for sections to the bottom of the list for that section (in order by name)
                var personalLinkSectionOrderService = new PersonalLinkSectionOrderService(rockContext);

                var lastSectionOrder = personalLinkSectionOrderService.Queryable().Where(a => a.PersonAlias.PersonId == currentPerson.Id).Max(a => ( int? )a.Order) ?? 0;
                foreach (var missingSectionOrder in missingSectionOrders)
                {
                    missingSectionOrder.Order = lastSectionOrder++;
                }

                personalLinkSectionOrderService.AddRange(missingSectionOrders);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the section order query.
        /// Use this to make sure to get the best match for in cases where
        /// a person has more than one sort order for a section (which could happen if there was person merge)
        /// </summary>
        /// <remarks>
        /// If you are unsure if there are some sections that don't have an order, use <see cref="AddMissingPersonalLinkSectionOrders(Person)"/> first.
        /// </remarks>
        /// <param name="person">The person.</param>
        /// <returns>System.Linq.IQueryable&lt;Rock.Model.PersonalLinkSectionOrder&gt;.</returns>
        public IOrderedQueryable <PersonalLinkSectionOrder> GetSectionOrderQuery(Person person)
        {
            var rockContext = this.Context as RockContext;

            var personAliasQuery = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == person.Id);

            // There could be duplicate Orders for a Section for a person if the person was merged.
            // So, to ensure a consistent Order winner, also sort by ModifiedDateTime. That will
            // ensure the the most recent sort will be one the current person sees.
            var personalLinkSectionOrder = new PersonalLinkSectionOrderService(rockContext).Queryable()
                                           .Where(a => personAliasQuery.Any(xx => xx.Id == a.PersonAliasId))
                                           .GroupBy(a => a.SectionId)
                                           .Select(a => a.OrderBy(xx => xx.Order).ThenByDescending(xx => xx.ModifiedDateTime).FirstOrDefault())
                                           .OrderBy(a => a.Order);

            return(personalLinkSectionOrder);
        }
Пример #3
0
        /// <summary>
        /// Creates the email communication.
        /// </summary>
        /// <param name="createEmailCommunicationArgs">The create email communication arguments.</param>
        /// <returns></returns>
        public Communication CreateEmailCommunication(CreateEmailCommunicationArgs createEmailCommunicationArgs)
        {
            var recipients            = createEmailCommunicationArgs.Recipients;
            var senderPersonAliasId   = createEmailCommunicationArgs.SenderPersonAliasId;
            var fromName              = createEmailCommunicationArgs.FromName;
            var fromAddress           = createEmailCommunicationArgs.FromAddress;
            var replyTo               = createEmailCommunicationArgs.ReplyTo;
            var subject               = createEmailCommunicationArgs.Subject;
            var message               = createEmailCommunicationArgs.Message;
            var bulkCommunication     = createEmailCommunicationArgs.BulkCommunication;
            var sendDateTime          = createEmailCommunicationArgs.SendDateTime;
            var recipientStatus       = createEmailCommunicationArgs.RecipientStatus;
            var systemCommunicationId = createEmailCommunicationArgs.SystemCommunicationId;

            var recipientsWithPersonIds       = recipients.Where(a => a.PersonId.HasValue).Select(a => a.PersonId).ToList();
            var recipientEmailsUnknownPersons = recipients.Where(a => a.PersonId == null).Select(a => a.EmailAddress);

            /*
             * 4-MAY-2022 DMV
             *
             * In tracking down alleged duplicate communications we discovered
             * that duplicates could be sent to the same person if they are in the
             * recipient list more that once with mulitple Person Alias IDs.
             * This could have occured through a person merge or other data changes
             * in Rock. This code removes those duplicates from the list before
             * sending the communication.
             *
             */

            var recipientPersonList = new PersonAliasService(( RockContext )Context)
                                      .GetPrimaryAliasQuery()
                                      .Where(pa => recipientsWithPersonIds.Contains(pa.PersonId))
                                      .Select(a => a.Person)
                                      .ToList();

            if (!recipientPersonList.Any() && recipientEmailsUnknownPersons.Any(a => a != null))
            {
                // For backwards compatibility, if no PersonIds where specified, but there are recipients that are only specified by EmailAddress, take a guess at the personIds by looking for matching email addresses
                recipientPersonList = new PersonService(( RockContext )Context)
                                      .Queryable()
                                      .Where(p => recipientEmailsUnknownPersons.Contains(p.Email))
                                      .ToList();
            }

            if (!recipientPersonList.Any())
            {
                return(null);
            }

            var communication = new Communication
            {
                CommunicationType     = CommunicationType.Email,
                Status                = CommunicationStatus.Approved,
                ReviewedDateTime      = RockDateTime.Now,
                ReviewerPersonAliasId = senderPersonAliasId,
                SenderPersonAliasId   = senderPersonAliasId
            };

            communication.FromName              = fromName.TrimForMaxLength(communication, "FromName");
            communication.FromEmail             = fromAddress.TrimForMaxLength(communication, "FromEmail");
            communication.ReplyToEmail          = replyTo.TrimForMaxLength(communication, "ReplyToEmail");
            communication.Subject               = subject.TrimForMaxLength(communication, "Subject");
            communication.Message               = message;
            communication.IsBulkCommunication   = bulkCommunication;
            communication.FutureSendDateTime    = null;
            communication.SendDateTime          = sendDateTime;
            communication.SystemCommunicationId = systemCommunicationId;
            Add(communication);

            // add each person as a recipient to the communication
            foreach (var person in recipientPersonList)
            {
                var personAliasId = person.PrimaryAliasId;
                if (!personAliasId.HasValue)
                {
                    continue;
                }

                var communicationRecipient = new CommunicationRecipient
                {
                    PersonAliasId = personAliasId.Value,
                    Status        = recipientStatus,
                    SendDateTime  = sendDateTime
                };
                communication.Recipients.Add(communicationRecipient);
            }

            return(communication);
        }
Пример #4
0
            /// <summary>
            /// Gets current login's LastModifiedDateTime <see cref="Rock.Model.PersonalLink" /> data from  <see cref="System.Web.SessionState">Session</see>.
            /// </summary>
            /// <remarks>
            /// We cache PersonalLinksLastUpdateDateTime in session so that we know if the LocalStorage of PersonalLinks needs to be updated.
            /// </remarks>
            public static DateTime?GetPersonalLinksLastModifiedDateTime(Person currentPerson)
            {
                if (currentPerson == null)
                {
                    return(null);
                }

                DateTime?lastModifiedDateTime = null;

                if (HttpContext.Current?.Session != null)
                {
                    // If we already got the LastModifiedDateTime, we'll store it in session so that we don't have to keep asking
                    lastModifiedDateTime = HttpContext.Current.Session[SessionKey.PersonalLinksLastUpdateDateTime] as DateTime?;
                }
                else
                {
                    // If we dont' have a Session, see if we are storing it for the current request;
                    lastModifiedDateTime = HttpContext.Current?.Items[SessionKey.PersonalLinksLastUpdateDateTime] as DateTime?;
                }

                if (lastModifiedDateTime.HasValue)
                {
                    return(lastModifiedDateTime);
                }

                // NOTE: Session can be null (probably because it is a REST call). Or maybe it hasn't been set in Session yet So, we'll get it from the Database;
                var rockContext = new RockContext();

                var personAliasQuery = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == currentPerson.Id);

                var sectionLastModifiedDateTimeQuery = new PersonalLinkSectionService(rockContext)
                                                       .Queryable()
                                                       .Where(a => !a.IsShared && a.ModifiedDateTime.HasValue && a.PersonAliasId.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId))
                                                       .Select(a => a.ModifiedDateTime);

                var linkLastModifiedDateTimeQuery = new PersonalLinkService(rockContext)
                                                    .Queryable()
                                                    .Where(a => a.ModifiedDateTime.HasValue && a.PersonAliasId.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId))
                                                    .Select(a => a.ModifiedDateTime);

                var linkOrderLastModifiedDateTimeQuery = new PersonalLinkSectionOrderService(rockContext)
                                                         .Queryable()
                                                         .Where(a => a.ModifiedDateTime.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId))
                                                         .Select(a => a.ModifiedDateTime);

                lastModifiedDateTime = sectionLastModifiedDateTimeQuery.Union(linkLastModifiedDateTimeQuery).Union(linkOrderLastModifiedDateTimeQuery).Max(a => a);

                if (HttpContext.Current?.Session != null)
                {
                    if (lastModifiedDateTime == null)
                    {
                        // If LastModifiedDateTime is still null, they don't have any personal links,
                        // So we'll set LastModifiedDateTime to Midnight (so it doesn't keep checking the database)
                        lastModifiedDateTime = RockDateTime.Today;
                    }

                    // If we already got the LastModifiedDateTime, we'll store it in session so that we don't have to keep asking
                    HttpContext.Current.Session[SessionKey.PersonalLinksLastUpdateDateTime] = lastModifiedDateTime;
                }
                else
                {
                    // if we don't have Session, store it in the current request (just in case this called multiple times in the same request)
                    if (HttpContext.Current != null)
                    {
                        HttpContext.Current.Items[SessionKey.PersonalLinksLastUpdateDateTime] = lastModifiedDateTime;
                    }
                }

                return(lastModifiedDateTime);
            }
Пример #5
0
        /// <summary>
        /// Returns a queryable of the ordered personal link sections (shared and non-shared) that would be available to the specified person.
        /// They will be sorted by the order that the specified person put them in,
        /// </summary>
        /// <param name="currentPerson">The current person.</param>
        /// <returns>IOrderedQueryable&lt;PersonalLinkSection&gt;.</returns>
        public IOrderedQueryable <PersonalLinkSection> GetOrderedPersonalLinkSectionsQuery(Person currentPerson)
        {
            var rockContext = this.Context as RockContext;

            var personAliasQuery  = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == currentPerson.Id);
            var sectionOrderQuery = GetSectionOrderQuery(currentPerson);

            var orderedPersonalLinkSectionQuery = new PersonalLinkSectionService(rockContext)
                                                  .Queryable()
                                                  .Where(a => a.IsShared || (a.PersonAliasId.HasValue && personAliasQuery.Any(xx => xx.Id == a.PersonAliasId.Value)))
                                                  .OrderBy(a => sectionOrderQuery.Where(xx => xx.SectionId == a.Id).Select(s => s.Order).FirstOrDefault())
                                                  .ThenBy(a => a.Name);

            return(orderedPersonalLinkSectionQuery);
        }