/// <summary>
 /// Returns a queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> by <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/>
 /// </summary>
 /// <param name="communicationId">A <see cref="System.Int32"/> representing the CommunicationId of the <see cref="Rock.Model.Communication"/> to search by.</param>
 /// <param name="status">A <see cref="Rock.Model.CommunicationRecipientStatus"/> Enum value representing the status of the communication submission.</param>
 /// <returns>A queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> for the specified <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/></returns>
 public IQueryable<Rock.Model.CommunicationRecipient> Get( int communicationId, CommunicationRecipientStatus status )
 {
     return Queryable( "Communication,PersonAlias.Person" )
         .Where( r =>
             r.CommunicationId == communicationId &&
             r.Status == status && r.PersonAlias.Person.IsDeceased == false );
 }
Example #2
0
 /// <summary>
 /// Creates the email communication
 /// </summary>
 /// <param name="recipients">The recipients.</param>
 /// <param name="fromName">From name.</param>
 /// <param name="fromAddress">From address.</param>
 /// <param name="replyTo">The reply to.</param>
 /// <param name="subject">The subject.</param>
 /// <param name="message">The message.</param>
 /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param>
 /// <param name="sendDateTime">The send date time.</param>
 /// <param name="recipientStatus">The recipient status.</param>
 /// <param name="senderPersonAliasId">The sender person alias identifier.</param>
 /// <returns></returns>
 public Communication CreateEmailCommunication
 (
     List <RockEmailMessageRecipient> recipients,
     string fromName,
     string fromAddress,
     string replyTo,
     string subject,
     string message,
     bool bulkCommunication,
     DateTime?sendDateTime,
     CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
     int?senderPersonAliasId = null)
 {
     return(CreateEmailCommunication(new CreateEmailCommunicationArgs
     {
         Recipients = recipients,
         FromName = fromName,
         FromAddress = fromAddress,
         ReplyTo = replyTo,
         Subject = subject,
         Message = message,
         BulkCommunication = bulkCommunication,
         SendDateTime = sendDateTime,
         RecipientStatus = recipientStatus,
         SenderPersonAliasId = senderPersonAliasId,
         SystemCommunicationId = null
     }));
 }
 /// <summary>
 /// Returns a queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> by <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/>
 /// </summary>
 /// <param name="communicationId">A <see cref="System.Int32"/> representing the CommunicationId of the <see cref="Rock.Model.Communication"/> to search by.</param>
 /// <param name="status">A <see cref="Rock.Model.CommunicationRecipientStatus"/> Enum value representing the status of the communication submission.</param>
 /// <returns>A queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> for the specified <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/></returns>
 public IQueryable<Rock.Model.CommunicationRecipient> Get( int communicationId, CommunicationRecipientStatus status )
 {
     return Queryable( "Communication" )
         .Where( r => 
             r.CommunicationId == communicationId  &&
             r.Status == status);
 }
        /// <summary>
        /// Creates the email communication.
        /// </summary>
        /// <param name="recipientEmails">The recipient emails.</param>
        /// <param name="fromName">From name.</param>
        /// <param name="fromAddress">From address.</param>
        /// <param name="replyTo">The reply to.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="message">The message.</param>
        /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param>\
        /// <param name="sendDateTime">The send date time.</param>
        /// <param name="recipientStatus">The recipient status.</param>
        /// <param name="senderPersonAliasId">The sender person alias identifier.</param>
        /// <returns></returns>
        public Communication CreateEmailCommunication
        (
            List <string> recipientEmails,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string message,
            bool bulkCommunication,
            DateTime?sendDateTime,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            var recipients = new PersonService((RockContext)Context)
                             .Queryable()
                             .Where(p => recipientEmails.Contains(p.Email))
                             .ToList();

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

            var communication = new Communication
            {
                CommunicationType   = CommunicationType.Email,
                Status              = CommunicationStatus.Approved,
                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;
            Add(communication);

            // add each person as a recipient to the communication
            foreach (var person in recipients)
            {
                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);
        }
Example #5
0
        public Communication CreateEmailCommunication
        (
            List <string> recipientEmails,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string message,
            bool bulkCommunication,
            DateTime?sendDateTime,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            var recipients = new PersonService(( RockContext )Context)
                             .Queryable()
                             .Where(p => recipientEmails.Contains(p.Email))
                             .ToList()
                             .Select(a => new RockEmailMessageRecipient(a, null))
                             .ToList();

            return(CreateEmailCommunication(new CreateEmailCommunicationArgs
            {
                Recipients = recipients,
                FromName = fromName,
                FromAddress = fromAddress,
                ReplyTo = replyTo,
                Subject = subject,
                Message = message,
                BulkCommunication = bulkCommunication,
                SendDateTime = sendDateTime,
                RecipientStatus = recipientStatus,
                SenderPersonAliasId = senderPersonAliasId
            }));
        }
 /// <summary>
 /// Returns a queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> by <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/>
 /// </summary>
 /// <param name="communicationId">A <see cref="System.Int32"/> representing the CommunicationId of the <see cref="Rock.Model.Communication"/> to search by.</param>
 /// <param name="status">A <see cref="Rock.Model.CommunicationRecipientStatus"/> Enum value representing the status of the communication submission.</param>
 /// <returns>A queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> for the specified <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/></returns>
 public IQueryable<Rock.Model.CommunicationRecipient> Get( int communicationId, CommunicationRecipientStatus status )
 {
     return Queryable( "Communication" )
         .Where( r =>
             r.CommunicationId == communicationId &&
             r.Status == status &&
             ( !r.Person.IsDeceased.HasValue || !r.Person.IsDeceased.Value ) );
 }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            string[] selectionValues = selection.Split('|');
            var      rockContext     = ( RockContext )serviceInstance.Context;

            if (selectionValues.Length >= 2)
            {
                var communicationId         = selectionValues[0].AsInteger();
                var communicationStatusType = selectionValues[1].ConvertToEnum <CommunicationStatusType>();
                var communicationRecipients = new CommunicationRecipientService(rockContext).GetByCommunicationId(communicationId);

                var interactionChannelCommunication = new InteractionChannelService(rockContext).Get(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid());
                var interactionQuery = new InteractionService(rockContext).Queryable()
                                       .Where(a => a.InteractionComponent.ChannelId == interactionChannelCommunication.Id &&
                                              a.InteractionComponent.EntityId.Value == communicationId);
                CommunicationRecipientStatus[] sentStatus = new CommunicationRecipientStatus[] { CommunicationRecipientStatus.Opened, CommunicationRecipientStatus.Delivered };

                switch (communicationStatusType)
                {
                case CommunicationStatusType.Open:
                {
                    interactionQuery        = interactionQuery.Where(a => a.Operation == "Opened");
                    communicationRecipients = communicationRecipients.Where(a => sentStatus.Contains(a.Status) && interactionQuery.Any(b => b.EntityId == a.Id));
                }
                break;

                case CommunicationStatusType.Clicked:
                {
                    interactionQuery        = interactionQuery.Where(a => a.Operation == "Click");
                    communicationRecipients = communicationRecipients.Where(a => sentStatus.Contains(a.Status) && interactionQuery.Any(b => b.EntityId == a.Id));
                }
                break;

                case CommunicationStatusType.Unopened:
                {
                    interactionQuery        = interactionQuery.Where(a => a.Operation == "Click" || a.Operation == "Opened");
                    communicationRecipients = communicationRecipients.Where(a => sentStatus.Contains(a.Status) && !interactionQuery.Any(b => b.EntityId == a.Id));
                }
                break;

                case CommunicationStatusType.Failed:
                default:
                {
                    CommunicationRecipientStatus[] failedStatus = new CommunicationRecipientStatus[] { CommunicationRecipientStatus.Failed };
                    communicationRecipients = communicationRecipients.Where(a => failedStatus.Contains(a.Status));
                }
                break;
                }

                var qry = new PersonService(( RockContext )serviceInstance.Context).Queryable()
                          .Where(p => communicationRecipients.Any(x => x.PersonAlias.PersonId == p.Id));

                return(FilterExpressionExtractor.Extract <Rock.Model.Person>(qry, parameterExpression, "p"));
            }

            return(null);
        }
Example #8
0
        /// <summary>
        /// Creates the email communication.
        /// </summary>
        /// <param name="recipientEmails">The recipient emails.</param>
        /// <param name="fromName">From name.</param>
        /// <param name="fromAddress">From address.</param>
        /// <param name="replyTo">The reply to.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="htmlMessage">The HTML message.</param>
        /// <param name="textMessage">The text message.</param>
        /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param>
        /// <param name="recipientStatus">The recipient status.</param>
        /// <param name="senderPersonAliasId">The sender person alias identifier.</param>
        /// <returns></returns>
        public Communication CreateEmailCommunication(
            List <string> recipientEmails,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string htmlMessage,
            string textMessage,
            bool bulkCommunication,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            var recipients = new PersonService((RockContext)this.Context)
                             .Queryable()
                             .Where(p => recipientEmails.Contains(p.Email))
                             .ToList();

            if (recipients.Any())
            {
                Rock.Model.Communication communication = new Rock.Model.Communication();
                communication.Status = CommunicationStatus.Approved;
                communication.SenderPersonAliasId = senderPersonAliasId;
                communication.Subject             = subject;
                Add(communication);

                communication.IsBulkCommunication = bulkCommunication;
                communication.MediumEntityTypeId  = EntityTypeCache.Read("Rock.Communication.Medium.Email").Id;
                communication.FutureSendDateTime  = null;

                // add each person as a recipient to the communication
                foreach (var person in recipients)
                {
                    int?personAliasId = person.PrimaryAliasId;
                    if (personAliasId.HasValue)
                    {
                        var communicationRecipient = new CommunicationRecipient();
                        communicationRecipient.PersonAliasId = personAliasId.Value;
                        communicationRecipient.Status        = recipientStatus;
                        communication.Recipients.Add(communicationRecipient);
                    }
                }

                // add the MediumData to the communication
                communication.MediumData.Clear();
                communication.MediumData.Add("FromName", fromName);
                communication.MediumData.Add("FromAddress", fromAddress);
                communication.MediumData.Add("ReplyTo", replyTo);
                communication.MediumData.Add("Subject", subject);
                communication.MediumData.Add("HtmlMessage", htmlMessage);
                communication.MediumData.Add("TextMessage", textMessage);

                return(communication);
            }

            return(null);
        }
        /// <summary>
        /// Creates the email communication.
        /// </summary>
        /// <param name="recipientEmails">The recipient emails.</param>
        /// <param name="fromName">From name.</param>
        /// <param name="fromAddress">From address.</param>
        /// <param name="replyTo">The reply to.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="htmlMessage">The HTML message.</param>
        /// <param name="textMessage">The text message.</param>
        /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param>
        /// <param name="recipientStatus">The recipient status.</param>
        /// <param name="senderPersonAliasId">The sender person alias identifier.</param>
        /// <returns></returns>
        public Communication CreateEmailCommunication( 
            List<string> recipientEmails, 
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string htmlMessage,
            string textMessage,
            bool bulkCommunication, 
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered, 
            int? senderPersonAliasId = null )
        {
            var recipients = new PersonService( (RockContext)this.Context )
                .Queryable()
                .Where( p => recipientEmails.Contains( p.Email ) )
                .ToList();

            if ( recipients.Any() )
            {
                Rock.Model.Communication communication = new Rock.Model.Communication();
                communication.Status = CommunicationStatus.Approved;
                communication.SenderPersonAliasId = senderPersonAliasId;
                communication.Subject = subject;
                Add( communication );

                communication.IsBulkCommunication = bulkCommunication;
                communication.MediumEntityTypeId = EntityTypeCache.Read( "Rock.Communication.Medium.Email" ).Id;
                communication.FutureSendDateTime = null;

                // add each person as a recipient to the communication
                foreach ( var person in recipients )
                {
                    int? personAliasId = person.PrimaryAliasId;
                    if ( personAliasId.HasValue )
                    {
                        var communicationRecipient = new CommunicationRecipient();
                        communicationRecipient.PersonAliasId = personAliasId.Value;
                        communicationRecipient.Status = recipientStatus;
                        communication.Recipients.Add( communicationRecipient );
                    }
                }

                // add the MediumData to the communication
                communication.MediumData.Clear();
                communication.MediumData.Add( "FromName", fromName );
                communication.MediumData.Add( "FromAddress", fromAddress );
                communication.MediumData.Add( "ReplyTo", replyTo );
                communication.MediumData.Add( "Subject", subject );
                communication.MediumData.Add( "HtmlMessage", htmlMessage );
                communication.MediumData.Add( "TextMessage", textMessage );

                return communication;
            }

            return null;
        }
Example #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Recipient" /> class.
 /// </summary>
 /// <param name="personId">The person id.</param>
 /// <param name="personName">Name of the person.</param>
 /// <param name="status">The status.</param>
 public Recipient(Person person, CommunicationRecipientStatus status, string statusNote = "", string openedClient = "", DateTime?openedDateTime = null)
 {
     PersonId        = person.Id;
     PersonName      = person.FullName;
     HasSmsNumber    = person.PhoneNumbers.Any(p => p.IsMessagingEnabled);
     Email           = person.Email;
     IsEmailActive   = person.IsEmailActive ?? true;
     EmailNote       = person.EmailNote;
     EmailPreference = person.EmailPreference;
     Status          = status;
     StatusNote      = statusNote;
     OpenedClient    = openedClient;
     OpenedDateTime  = openedDateTime;
 }
 public Communication CreateEmailCommunication
 (
     List <string> recipientEmails,
     string fromName,
     string fromAddress,
     string replyTo,
     string subject,
     string htmlMessage,
     string textMessage,
     bool bulkCommunication,
     CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
     int?senderPersonAliasId = null)
 {
     return(CreateEmailCommunication(recipientEmails, fromName, fromAddress, replyTo, subject, htmlMessage, bulkCommunication, recipientStatus, senderPersonAliasId));
 }
        public Communication CreateEmailCommunication
        (
            List <string> recipientEmails,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string message,
            bool bulkCommunication,
            DateTime?sendDateTime,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            var recipients = new PersonService(( RockContext )Context)
                             .Queryable()
                             .Where(p => recipientEmails.Contains(p.Email))
                             .ToList();

            return(this.CreateEmailCommunication(recipients.Select(a => new RockEmailMessageRecipient(a, null)).ToList(), fromName, fromAddress, replyTo, subject, message, bulkCommunication, sendDateTime, recipientStatus, senderPersonAliasId));
        }
        public Communication CreateEmailCommunication
        (
            List <string> recipientEmails,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string message,
            bool bulkCommunication,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            DateTime?sendDateTime = null;

            if (recipientStatus == CommunicationRecipientStatus.Delivered)
            {
                sendDateTime = RockDateTime.Now;
            }

            return(CreateEmailCommunication(recipientEmails, fromName, fromAddress, replyTo, subject, message, bulkCommunication, sendDateTime, recipientStatus, senderPersonAliasId));
        }
 /// <summary>
 /// Gets the Communication Recipients for the specified status.
 /// </summary>
 /// <param name="communicationRecipient">The communication recipient.</param>
 /// <param name="communicationRecipientStatus">The communication recipient status.</param>
 /// <returns></returns>
 public static IQueryable <CommunicationRecipient> ByStatus(this IQueryable <CommunicationRecipient> communicationRecipient, CommunicationRecipientStatus communicationRecipientStatus)
 {
     return(communicationRecipient.Where(x => x.Status == communicationRecipientStatus));
 }
 /// <summary>
 /// Returns a queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> by <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/>
 /// </summary>
 /// <param name="communicationId">A <see cref="System.Int32"/> representing the CommunicationId of the <see cref="Rock.Model.Communication"/> to search by.</param>
 /// <param name="status">A <see cref="Rock.Model.CommunicationRecipientStatus"/> Enum value representing the status of the communication submission.</param>
 /// <returns>A queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> for the specified <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/></returns>
 public IQueryable <Rock.Model.CommunicationRecipient> Get(int communicationId, CommunicationRecipientStatus status)
 {
     return(Queryable("Communication,PersonAlias.Person")
            .Where(r =>
                   r.CommunicationId == communicationId &&
                   r.Status == status && r.PersonAlias.Person.IsDeceased == false));
 }
Example #16
0
        /// <summary>
        /// Creates the email communication
        /// </summary>
        /// <param name="recipients">The recipients.</param>
        /// <param name="fromName">From name.</param>
        /// <param name="fromAddress">From address.</param>
        /// <param name="replyTo">The reply to.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="message">The message.</param>
        /// <param name="bulkCommunication">if set to <c>true</c> [bulk communication].</param>
        /// <param name="sendDateTime">The send date time.</param>
        /// <param name="recipientStatus">The recipient status.</param>
        /// <param name="senderPersonAliasId">The sender person alias identifier.</param>
        /// <returns></returns>
        public Communication CreateEmailCommunication
        (
            List <RockEmailMessageRecipient> recipients,
            string fromName,
            string fromAddress,
            string replyTo,
            string subject,
            string message,
            bool bulkCommunication,
            DateTime?sendDateTime,
            CommunicationRecipientStatus recipientStatus = CommunicationRecipientStatus.Delivered,
            int?senderPersonAliasId = null)
        {
            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);

            var recipientPersonList = new PersonService(( RockContext )Context)
                                      .Queryable()
                                      .Where(p => recipientsWithPersonIds.Contains(p.Id))
                                      .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,
                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;
            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);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="Recipient" /> class.
 /// </summary>
 /// <param name="personId">The person id.</param>
 /// <param name="personName">Name of the person.</param>
 /// <param name="status">The status.</param>
 public Recipient( Person person, bool personHasSMS, CommunicationRecipientStatus status, string statusNote = "", string openedClient = "", DateTime? openedDateTime = null )
 {
     PersonId = person.Id;
     PersonName = person.FullName;
     IsDeceased = person.IsDeceased;
     HasSmsNumber = personHasSMS;
     Email = person.Email;
     IsEmailActive = person.IsEmailActive;
     EmailNote = person.EmailNote;
     EmailPreference = person.EmailPreference;
     Status = status;
     StatusNote = statusNote;
     OpenedClient = openedClient;
     OpenedDateTime = openedDateTime;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Recipient" /> class.
 /// </summary>
 /// <param name="personId">The person id.</param>
 /// <param name="personName">Name of the person.</param>
 /// <param name="status">The status.</param>
 public Recipient( Person person, CommunicationRecipientStatus status, string statusNote = "", string openedClient = "", DateTime? openedDateTime = null )
 {
     PersonId = person.Id;
     PersonName = person.FullName;
     IsDeceased = person.IsDeceased ?? false;
     HasSmsNumber = person.PhoneNumbers.Any( p => p.IsMessagingEnabled );
     Email = person.Email;
     IsEmailActive = person.IsEmailActive ?? true;
     EmailNote = person.EmailNote;
     EmailPreference = person.EmailPreference;
     Status = status;
     StatusNote = statusNote;
     OpenedClient = openedClient;
     OpenedDateTime = openedDateTime;
 }
Example #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SaveCommunicationTransaction"/> class.
 /// </summary>
 public SaveCommunicationTransaction()
 {
     RecipientStatus   = CommunicationRecipientStatus.Delivered;
     BulkCommunication = false;
 }
 /// <summary>
 /// Returns a queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> by <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/>
 /// </summary>
 /// <param name="communicationId">A <see cref="System.Int32"/> representing the CommunicationId of the <see cref="Rock.Model.Communication"/> to search by.</param>
 /// <param name="status">A <see cref="Rock.Model.CommunicationRecipientStatus"/> Enum value representing the status of the communication submission.</param>
 /// <returns>A queryable collection of <see cref="Rock.Model.CommunicationRecipient">CommunicationRecipients</see> for the specified <see cref="Rock.Model.Communication"/> and <see cref="Rock.Model.CommunicationRecipientStatus"/></returns>
 public IQueryable <Rock.Model.CommunicationRecipient> Get(int communicationId, CommunicationRecipientStatus status)
 {
     return(Repository.AsQueryable()
            .Where(r =>
                   r.CommunicationId == communicationId &&
                   r.Status == status));
 }
        /// <summary>
        /// Shows the charts.
        /// </summary>
        public void ShowCharts()
        {
            var rockContext = new RockContext();

            hfCommunicationId.Value          = this.PageParameter("CommunicationId");
            hfCommunicationListGroupId.Value = this.PageParameter("CommunicationListId");

            int?   communicationId          = hfCommunicationId.Value.AsIntegerOrNull();
            string noDataMessageName        = string.Empty;
            int?   communicationListGroupId = hfCommunicationListGroupId.Value.AsIntegerOrNull();

            if (communicationId.HasValue)
            {
                // specific communication specified
                var communication = new CommunicationService(rockContext).Get(communicationId.Value);
                if (communication != null)
                {
                    lTitle.Text       = "Email Analytics: " + (communication.Name ?? communication.Subject);
                    noDataMessageName = communication.Name ?? communication.Subject;
                }
                else
                {
                    // Invalid Communication specified
                    nbCommunicationorCommunicationListFound.Visible = true;
                    nbCommunicationorCommunicationListFound.Text    = "Invalid communication specified";
                }
            }
            else if (communicationListGroupId.HasValue)
            {
                // specific communicationgroup specified
                var communicationListGroup = new GroupService(rockContext).Get(communicationListGroupId.Value);
                if (communicationListGroup != null)
                {
                    lTitle.Text       = "Email Analytics: " + communicationListGroup.Name;
                    noDataMessageName = communicationListGroup.Name;
                }
                else
                {
                    nbCommunicationorCommunicationListFound.Visible = true;
                    nbCommunicationorCommunicationListFound.Text    = "Invalid communication list group specified";
                }
            }
            else
            {
                // no specific communication or list specific, so just show overall stats
                lTitle.Text = "Email Analytics";
            }

            var interactionChannelCommunication = new InteractionChannelService(rockContext).Get(Rock.SystemGuid.InteractionChannel.COMMUNICATION.AsGuid());
            var interactionQuery = new InteractionService(rockContext).Queryable().Where(a => a.InteractionComponent.ChannelId == interactionChannelCommunication.Id);

            List <int> communicationIdList = null;

            if (communicationId.HasValue)
            {
                communicationIdList = new List <int>();
                communicationIdList.Add(communicationId.Value);
            }
            else if (communicationListGroupId.HasValue)
            {
                communicationIdList = new CommunicationService(rockContext).Queryable().Where(a => a.ListGroupId == communicationListGroupId).Select(a => a.Id).ToList();
            }

            if (communicationIdList != null)
            {
                interactionQuery = interactionQuery.Where(a => communicationIdList.Contains(a.InteractionComponent.EntityId.Value));
            }

            var interactionsList = interactionQuery
                                   .Select(a => new
            {
                a.InteractionDateTime,
                a.Operation,
                a.InteractionData,
                CommunicationRecipientId = a.EntityId
            })
                                   .ToList();

            List <SummaryInfo> interactionsSummary = new List <SummaryInfo>();
            TimeSpan           roundTimeSpan       = TimeSpan.FromDays(1);

            this.SeriesColorsJSON = this.GetAttributeValue("SeriesColors").SplitDelimitedValues().ToArray().ToJson();

            this.LineChartTimeFormat = "LL";

            if (interactionsList.Any())
            {
                var firstDateTime = interactionsList.Min(a => a.InteractionDateTime);
                var lastDateTime  = interactionsList.Max(a => a.InteractionDateTime);
                var weeksCount    = (lastDateTime - firstDateTime).TotalDays / 7;

                if (weeksCount > 26)
                {
                    // if there is more than 26 weeks worth, summarize by week
                    roundTimeSpan = TimeSpan.FromDays(7);
                }
                else if (weeksCount > 3)
                {
                    // if there is more than 3 weeks worth, summarize by day
                    roundTimeSpan = TimeSpan.FromDays(1);
                }
                else
                {
                    // if there is less than 3 weeks worth, summarize by hour
                    roundTimeSpan            = TimeSpan.FromHours(1);
                    this.LineChartTimeFormat = "LLLL";
                }
            }

            interactionsSummary = interactionsList.GroupBy(a => new { a.CommunicationRecipientId, a.Operation })
                                  .Select(a => new
            {
                InteractionSummaryDateTime = a.Min(b => b.InteractionDateTime).Round(roundTimeSpan),
                a.Key.CommunicationRecipientId,
                a.Key.Operation
            })
                                  .GroupBy(a => a.InteractionSummaryDateTime)
                                  .Select(x => new SummaryInfo
            {
                SummaryDateTime = x.Key,
                ClickCounts     = x.Count(xx => xx.Operation == "Click"),
                OpenCounts      = x.Count(xx => xx.Operation == "Opened")
            }).OrderBy(a => a.SummaryDateTime).ToList();

            var lineChartHasData = interactionsSummary.Any();

            openClicksLineChartCanvas.Style[HtmlTextWriterStyle.Display] = lineChartHasData ? string.Empty : "none";
            nbOpenClicksLineChartMessage.Visible = !lineChartHasData;
            nbOpenClicksLineChartMessage.Text    = "No communications activity" + (!string.IsNullOrEmpty(noDataMessageName) ? " for " + noDataMessageName : string.Empty);

            this.LineChartDataLabelsJSON = "[" + interactionsSummary.Select(a => "new Date('" + a.SummaryDateTime.ToString("o") + "')").ToList().AsDelimited(",\n") + "]";

            List <int> cumulativeClicksList = new List <int>();
            List <int> clickCountsList      = interactionsSummary.Select(a => a.ClickCounts).ToList();
            int        clickCountsSoFar     = 0;

            foreach (var clickCounts in clickCountsList)
            {
                clickCountsSoFar += clickCounts;
                cumulativeClicksList.Add(clickCountsSoFar);
            }

            this.LineChartDataClicksJSON = cumulativeClicksList.ToJson();

            List <int> cumulativeOpensList = new List <int>();
            List <int> openCountsList      = interactionsSummary.Select(a => a.OpenCounts).ToList();
            int        openCountsSoFar     = 0;

            foreach (var openCounts in openCountsList)
            {
                openCountsSoFar += openCounts;
                cumulativeOpensList.Add(openCountsSoFar);
            }

            this.LineChartDataOpensJSON = cumulativeOpensList.ToJson();

            int?deliveredRecipientCount = null;
            int?failedRecipientCount    = null;

            if (communicationIdList != null)
            {
                CommunicationRecipientStatus[] sentStatus   = new CommunicationRecipientStatus[] { CommunicationRecipientStatus.Opened, CommunicationRecipientStatus.Delivered };
                CommunicationRecipientStatus[] failedStatus = new CommunicationRecipientStatus[] { CommunicationRecipientStatus.Failed };
                deliveredRecipientCount = new CommunicationRecipientService(rockContext).Queryable().Where(a => sentStatus.Contains(a.Status) && communicationIdList.Contains(a.CommunicationId)).Count();
                failedRecipientCount    = new CommunicationRecipientService(rockContext).Queryable().Where(a => failedStatus.Contains(a.Status) && communicationIdList.Contains(a.CommunicationId)).Count();
            }

            List <int> unopenedCountsList = new List <int>();

            if (deliveredRecipientCount.HasValue)
            {
                int unopenedRemaining = deliveredRecipientCount.Value;
                foreach (var openCounts in openCountsList)
                {
                    unopenedRemaining = unopenedRemaining - openCounts;

                    // NOTE: just in case we have more recipients activity then there are recipient records, don't let it go negative
                    unopenedCountsList.Add(Math.Max(unopenedRemaining, 0));
                }

                this.LineChartDataUnOpenedJSON = unopenedCountsList.ToJson();
            }
            else
            {
                this.LineChartDataUnOpenedJSON = "null";
            }

            /* Actions Pie Chart and Stats */
            int totalOpens  = interactionsList.Where(a => a.Operation == "Opened").Count();
            int totalClicks = interactionsList.Where(a => a.Operation == "Click" && !string.IsNullOrEmpty(a.InteractionData)).Count();

            // Unique Opens is the number of times a Recipient opened at least once
            int uniqueOpens = interactionsList.Where(a => a.Operation == "Opened").GroupBy(a => a.CommunicationRecipientId).Count();

            // Unique Clicks is the number of times a Recipient clicked at least once in an email
            int uniqueClicks = interactionsList.Where(a => a.Operation == "Click" && !string.IsNullOrEmpty(a.InteractionData)).GroupBy(a => a.CommunicationRecipientId).Count();

            string actionsStatFormatNumber  = "<span class='{0}'>{1}</span><br><span class='js-actions-statistic' title='{2}' style='font-size: 45px; font-weight: 700; line-height: 40px;'>{3:#,##0}</span>";
            string actionsStatFormatPercent = "<span class='{0}'>{1}</span><br><span class='js-actions-statistic' title='{2}' style='font-size: 45px; font-weight: 700; line-height: 40px;'>{3:P2}</span>";

            if (deliveredRecipientCount.HasValue)
            {
                lDelivered.Text        = string.Format(actionsStatFormatNumber, "label label-default", "Delivered", "The number of recipients that the email was successfully delivered to", deliveredRecipientCount);
                lPercentOpened.Text    = string.Format(actionsStatFormatPercent, "label label-opened", "Percent Opened", "The percent of the delivered emails that were opened at least once", deliveredRecipientCount > 0 ? ( decimal)uniqueOpens / deliveredRecipientCount : 0);
                lFailedRecipients.Text = string.Format(actionsStatFormatNumber, "label label-danger", "Failed Recipients", "The number of emails that failed to get delivered", failedRecipientCount);

                // just in case there are more opens then delivered, don't let it go negative
                var unopenedCount = Math.Max(deliveredRecipientCount.Value - uniqueOpens, 0);
                lUnopened.Text = string.Format(actionsStatFormatNumber, "label label-unopened", "Unopened", "The number of emails that were delivered but not yet opened", unopenedCount);
            }

            lUniqueOpens.Text = string.Format(actionsStatFormatNumber, "label label-opened", "Unique Opens", "The number of emails that were opened at least once", uniqueOpens);
            lTotalOpens.Text  = string.Format(actionsStatFormatNumber, "label label-opened", "Total Opens", "The total number of times the emails were opened, including ones that were already opened once", totalOpens);

            lUniqueClicks.Text = string.Format(actionsStatFormatNumber, "label label-clicked", "Unique Clicks", "The number of times a recipient clicked on a link at least once in any of the opened emails", uniqueClicks);
            lTotalClicks.Text  = string.Format(actionsStatFormatNumber, "label label-clicked", "Total Clicks", "The total number of times a link was clicked in any of the opened emails", totalClicks);

            if (uniqueOpens > 0)
            {
                lClickThroughRate.Text = string.Format(actionsStatFormatPercent, "label label-clicked", "Click Through Rate (CTR)", "The percent of emails that had at least one click", ( decimal )uniqueClicks / uniqueOpens);
            }
            else
            {
                lClickThroughRate.Text = string.Empty;
            }

            // action stats is [opens,clicks,unopened];
            var actionsStats = new int?[3];

            // "Opens" would be unique number that Clicked Or Opened, so subtract clicks so they aren't counted twice
            actionsStats[0] = uniqueOpens - uniqueClicks;
            actionsStats[1] = uniqueClicks;

            if (deliveredRecipientCount.HasValue)
            {
                // NOTE: just in case we have more recipients activity then there are recipient records, don't let it go negative
                actionsStats[2] = Math.Max(deliveredRecipientCount.Value - uniqueOpens, 0);
            }
            else
            {
                actionsStats[2] = null;
            }

            this.PieChartDataOpenClicksJSON = actionsStats.ToJson();

            var pieChartOpenClicksHasData = actionsStats.Sum() > 0;

            opensClicksPieChartCanvas.Style[HtmlTextWriterStyle.Display] = pieChartOpenClicksHasData ? string.Empty : "none";
            nbOpenClicksPieChartMessage.Visible = !pieChartOpenClicksHasData;
            nbOpenClicksPieChartMessage.Text    = "No communications activity" + (!string.IsNullOrEmpty(noDataMessageName) ? " for " + noDataMessageName : string.Empty);

            int interactionCount = interactionsList.Count();

            /* Clients-In-Use (Client Type) Pie Chart*/
            var clientsUsageByClientType = interactionQuery
                                           .GroupBy(a => (a.InteractionSession.DeviceType.ClientType ?? "Unknown").ToLower()).Select(a => new ClientTypeUsageInfo
            {
                ClientType   = a.Key,
                UsagePercent = a.Count() * 100.00M / interactionCount
            }).OrderByDescending(a => a.UsagePercent).ToList()
                                           .Where(a => !a.ClientType.Equals("Robot", StringComparison.OrdinalIgnoreCase)) // no robots
                                           .Select(a => new ClientTypeUsageInfo
            {
                ClientType   = a.ClientType,
                UsagePercent = Math.Round(a.UsagePercent, 2)
            }).ToList();

            this.PieChartDataClientLabelsJSON = clientsUsageByClientType.Select(a => string.IsNullOrEmpty(a.ClientType) ? "Unknown" : a.ClientType.Transform(To.TitleCase)).ToList().ToJson();
            this.PieChartDataClientCountsJSON = clientsUsageByClientType.Select(a => a.UsagePercent).ToList().ToJson();

            var clientUsageHasData = clientsUsageByClientType.Where(a => a.UsagePercent > 0).Any();

            clientsDoughnutChartCanvas.Style[HtmlTextWriterStyle.Display] = clientUsageHasData ? string.Empty : "none";
            nbClientsDoughnutChartMessage.Visible = !clientUsageHasData;
            nbClientsDoughnutChartMessage.Text    = "No client usage activity" + (!string.IsNullOrEmpty(noDataMessageName) ? " for " + noDataMessageName : string.Empty);

            /* Clients-In-Use (Application) Grid */
            var clientsUsageByApplication = interactionQuery
                                            .GroupBy(a => a.InteractionSession.DeviceType.Application).Select(a => new ApplicationUsageInfo
            {
                Application  = a.Key,
                UsagePercent = (a.Count() * 100.00M / interactionCount)
            }).OrderByDescending(a => a.UsagePercent).ToList();

            pnlClientApplicationUsage.Visible    = clientsUsageByApplication.Any();
            rptClientApplicationUsage.DataSource = clientsUsageByApplication;
            rptClientApplicationUsage.DataBind();

            /* Most Popular Links from Clicks*/
            var topClicks = interactionsList
                            .Where(a =>
                                   a.Operation == "Click" &&
                                   !string.IsNullOrEmpty(a.InteractionData) &&
                                   !a.InteractionData.Contains("/Unsubscribe/"))
                            .GroupBy(a => a.InteractionData)
                            .Select(a => new
            {
                LinkUrl          = a.Key,
                UniqueClickCount = a.GroupBy(x => x.CommunicationRecipientId).Count()
            })
                            .OrderByDescending(a => a.UniqueClickCount)
                            .Take(100)
                            .ToList();


            if (topClicks.Any())
            {
                int topLinkCount = topClicks.Max(a => a.UniqueClickCount);

                // CTR really only makes sense if we are showing data for a single communication, so only show if it's a single communication
                bool singleCommunication = communicationIdList != null && communicationIdList.Count == 1;

                var mostPopularLinksData = topClicks.Select(a => new TopLinksInfo
                {
                    PercentOfTop = ( decimal )a.UniqueClickCount * 100 / topLinkCount,
                    Url          = a.LinkUrl,
                    UniquesCount = a.UniqueClickCount,
                    CTRPercent   = singleCommunication ? a.UniqueClickCount * 100.00M / deliveredRecipientCount : ( decimal? )null
                }).ToList();

                pnlCTRHeader.Visible = singleCommunication;

                rptMostPopularLinks.DataSource = mostPopularLinksData;
                rptMostPopularLinks.DataBind();
                pnlMostPopularLinks.Visible = true;
            }
            else
            {
                pnlMostPopularLinks.Visible = false;
            }
        }
Example #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Recipient" /> class.
 /// </summary>
 /// <param name="personId">The person id.</param>
 /// <param name="personName">Name of the person.</param>
 /// <param name="status">The status.</param>
 public Recipient(int personId, string personName, CommunicationRecipientStatus status)
 {
     PersonId   = personId;
     PersonName = personName;
     Status     = status;
 }
Example #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Recipient" /> class.
 /// </summary>
 /// <param name="personId">The person id.</param>
 /// <param name="personName">Name of the person.</param>
 /// <param name="status">The status.</param>
 public Recipient( int personId, string personName, CommunicationRecipientStatus status )
 {
     PersonId = personId;
     PersonName = personName;
     Status = status;
 }