/// <summary>
        /// Binds the filter.
        /// </summary>
        private void BindFilter()
        {
            drpDates.DelimitedValues = rFilter.GetUserPreference("Date Range");

            ppPerson.Visible           = _person == null;
            ddlAttendanceGroup.Visible = _group == null && _person != null;
            ddlAttendanceGroup.Items.Clear();
            ddlAttendanceGroup.Items.Add(new ListItem());

            if (_person != null)
            {
                var rockContext = new RockContext();
                var qryGroup    = new GroupService(rockContext).Queryable();

                var qryPersonAttendance = new AttendanceService(rockContext).Queryable().Where(a => a.PersonAlias.PersonId == _person.Id);

                // only list groups that this person has attended before
                var groupList = qryGroup.Where(g => qryPersonAttendance.Any(a => a.GroupId == g.Id))
                                .OrderBy(a => a.Name)
                                .Select(a => new { a.Name, a.Id }).ToList();

                foreach (var group in groupList)
                {
                    ddlAttendanceGroup.Items.Add(new ListItem(group.Name, group.Id.ToString()));
                }

                ddlAttendanceGroup.SetValue(rFilter.GetUserPreference("Group").AsIntegerOrNull());
            }

            spSchedule.SetValue(rFilter.GetUserPreference("Schedule").AsIntegerOrNull());
        }
Пример #2
0
        private void ShowDetail(Guid personGuid)
        {
            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);

                var person = personService.Queryable("PhoneNumbers.NumberTypeValue,RecordTypeValue", true, true)
                             .FirstOrDefault(a => a.Guid == personGuid);

                if (person != null)
                {
                    lName.Text = person.FullName;

                    string photoTag = Rock.Model.Person.GetPhotoImageTag(person, 120, 120);
                    if (person.PhotoId.HasValue)
                    {
                        lPhoto.Text = string.Format("<div class='photoframe'><a href='{0}'>{1}</a></div>", person.PhotoUrl, photoTag);
                    }
                    else
                    {
                        lPhoto.Text = photoTag;
                    }


                    lGender.Text = person.Gender != Gender.Unknown ? person.Gender.ConvertToString() : "";

                    if (person.BirthDate.HasValue)
                    {
                        string ageText = (person.BirthYear.HasValue && person.BirthYear != DateTime.MinValue.Year) ?
                                         string.Format("{0} yrs old ", person.BirthDate.Value.Age()) : string.Empty;
                        lAge.Text = string.Format("{0} <small>({1})</small><br/>", ageText, person.BirthDate.Value.ToShortDateString());
                    }
                    else
                    {
                        lAge.Text = string.Empty;
                    }

                    lGrade.Text = person.GradeFormatted;

                    lEmail.Visible = !string.IsNullOrWhiteSpace(person.Email);
                    lEmail.Text    = person.GetEmailTag(ResolveRockUrl("/"), "btn btn-default", "<i class='fa fa-envelope'></i>");

                    // Get all family member from all families ( including self )
                    var allFamilyMembers = personService.GetFamilyMembers(person.Id, true).ToList();

                    // Add flag for this person in each family indicating if they are a child in family.
                    var childGuid     = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
                    var isFamilyChild = new Dictionary <int, bool>();
                    foreach (var thisPerson in allFamilyMembers.Where(m => m.PersonId == person.Id))
                    {
                        isFamilyChild.Add(thisPerson.GroupId, thisPerson.GroupRole.Guid.Equals(childGuid));
                    }

                    // Get the current url's root (without the person's guid)
                    string urlRoot = Request.Url.ToString().ReplaceCaseInsensitive(personGuid.ToString(), "");

                    // Get the other family members and the info needed for rendering
                    var familyMembers = allFamilyMembers.Where(m => m.PersonId != person.Id)
                                        .OrderBy(m => m.GroupId)
                                        .ThenBy(m => m.Person.BirthDate)
                                        .Select(m => new
                    {
                        Url        = urlRoot + m.Person.Guid.ToString(),
                        FullName   = m.Person.FullName,
                        Gender     = m.Person.Gender,
                        FamilyRole = m.GroupRole,
                        Note       = isFamilyChild[m.GroupId] ?
                                     (m.GroupRole.Guid.Equals(childGuid) ? " (Sibling)" : "(Parent)") :
                                     (m.GroupRole.Guid.Equals(childGuid) ? " (Child)" : "")
                    })
                                        .ToList();

                    rcwFamily.Visible     = familyMembers.Any();
                    rptrFamily.DataSource = familyMembers;
                    rptrFamily.DataBind();

                    rptrPhones.DataSource = person.PhoneNumbers.Where(p => !p.IsUnlisted).ToList();
                    rptrPhones.DataBind();

                    var schedules = new ScheduleService(rockContext)
                                    .Queryable().AsNoTracking()
                                    .Where(s => s.CheckInStartOffsetMinutes.HasValue)
                                    .ToList();

                    var scheduleIds = schedules.Select(s => s.Id).ToList();

                    var activeScheduleIds = new List <int>();
                    foreach (var schedule in schedules)
                    {
                        if (schedule.IsScheduleOrCheckInActive)
                        {
                            activeScheduleIds.Add(schedule.Id);
                        }
                    }

                    int?personAliasId = person.PrimaryAliasId;
                    if (!personAliasId.HasValue)
                    {
                        personAliasId = new PersonAliasService(rockContext).GetPrimaryAliasId(person.Id);
                    }

                    var attendances = new AttendanceService(rockContext)
                                      .Queryable("Schedule,Group,Location")
                                      .Where(a =>
                                             a.PersonAliasId.HasValue &&
                                             a.PersonAliasId == personAliasId &&
                                             a.ScheduleId.HasValue &&
                                             a.GroupId.HasValue &&
                                             a.LocationId.HasValue &&
                                             a.DidAttend.HasValue &&
                                             a.DidAttend.Value &&
                                             scheduleIds.Contains(a.ScheduleId.Value))
                                      .OrderByDescending(a => a.StartDateTime)
                                      .Take(20)
                                      .ToList()                                     // Run query to get recent most 20 checkins
                                      .OrderByDescending(a => a.StartDateTime)      // Then sort again by startdatetime and schedule start (which is not avail to sql query )
                                      .ThenByDescending(a => a.Schedule.StartTimeOfDay)
                                      .Select(a => new AttendanceInfo
                    {
                        Date       = a.StartDateTime,
                        GroupId    = a.Group.Id,
                        Group      = a.Group.Name,
                        LocationId = a.LocationId.Value,
                        Location   = a.Location.Name,
                        Schedule   = a.Schedule.Name,
                        IsActive   =
                            a.StartDateTime > DateTime.Today &&
                            activeScheduleIds.Contains(a.ScheduleId.Value)
                    }).ToList();

                    // Set active locations to be a link to the room in manager page
                    var qryParam = new Dictionary <string, string>();
                    qryParam.Add("Group", "");
                    qryParam.Add("Location", "");
                    foreach (var attendance in attendances.Where(a => a.IsActive))
                    {
                        qryParam["Group"]    = attendance.GroupId.ToString();
                        qryParam["Location"] = attendance.LocationId.ToString();
                        attendance.Location  = string.Format("<a href='{0}'>{1}</a>",
                                                             LinkedPageUrl("ManagerPage", qryParam), attendance.Location);
                    }

                    rcwCheckinHistory.Visible = attendances.Any();
                    gHistory.DataSource       = attendances;
                    gHistory.DataBind();
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Processes this action for a check-in family.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="family">The family.</param>
        /// <param name="preventDuplicateCheckin">if set to <c>true</c> [prevent duplicate checkin].</param>
        /// <returns></returns>
        public static bool ProcessForFamily(RockContext rockContext, CheckInFamily family, bool preventDuplicateCheckin)
        {
            if (family != null)
            {
                var personIds = family.People.Select(p => p.Person.Id).ToList();
                var today     = RockDateTime.Today;
                var tomorrow  = RockDateTime.Today.AddDays(1);

                var existingAttendance = new AttendanceService(rockContext)
                                         .Queryable().AsNoTracking()
                                         .Where(a =>
                                                a.StartDateTime.CompareTo(today) >= 0 &&
                                                a.StartDateTime.CompareTo(tomorrow) < 0 &&
                                                a.DidAttend.HasValue &&
                                                a.DidAttend.Value &&
                                                !a.EndDateTime.HasValue &&
                                                a.PersonAlias != null &&
                                                personIds.Contains(a.PersonAlias.PersonId) &&
                                                a.Occurrence.ScheduleId.HasValue)
                                         .Select(a => new
                {
                    PersonId   = a.PersonAlias.PersonId,
                    ScheduleId = a.Occurrence.ScheduleId.Value
                })
                                         .ToList();

                if (existingAttendance.Any())
                {
                    foreach (var person in family.People.ToList())
                    {
                        var attendedScheduleIds = existingAttendance.Where(a => a.PersonId == person.Person.Id).Select(a => a.ScheduleId).ToList();
                        if (attendedScheduleIds.Any())
                        {
                            foreach (var groupType in person.GroupTypes.ToList())
                            {
                                if (preventDuplicateCheckin || groupType.GroupType.GetAttributeValue("PreventDuplicateCheckin").AsBoolean())
                                {
                                    attendedScheduleIds.ForEach(s => groupType.AvailableForSchedule.Remove(s));

                                    if (!groupType.AvailableForSchedule.Any())
                                    {
                                        person.GroupTypes.Remove(groupType);
                                    }
                                    else
                                    {
                                        foreach (var group in groupType.Groups.ToList())
                                        {
                                            attendedScheduleIds.ForEach(s => group.AvailableForSchedule.Remove(s));
                                            if (!group.AvailableForSchedule.Any())
                                            {
                                                groupType.Groups.Remove(group);
                                            }
                                            else
                                            {
                                                foreach (var location in group.Locations.ToList())
                                                {
                                                    attendedScheduleIds.ForEach(s => location.AvailableForSchedule.Remove(s));
                                                    if (!location.AvailableForSchedule.Any())
                                                    {
                                                        group.Locations.Remove(location);
                                                    }
                                                    else
                                                    {
                                                        foreach (var schedule in location.Schedules)
                                                        {
                                                            if (schedule.PreSelected && !location.AvailableForSchedule.Contains(schedule.Schedule.Id))
                                                            {
                                                                schedule.PreSelected  = false;
                                                                location.PreSelected  = false;
                                                                group.PreSelected     = false;
                                                                groupType.PreSelected = false;
                                                            }
                                                        }
                                                    }
                                                }
                                                if (group.Locations.Count == 0)
                                                {
                                                    groupType.Groups.Remove(group);
                                                }
                                            }
                                        }
                                        if (groupType.Groups.Count == 0)
                                        {
                                            person.GroupTypes.Remove(groupType);
                                        }
                                    }
                                }
                            }

                            if (person.GroupTypes.Count == 0)
                            {
                                family.People.Remove(person);
                            }
                        }
                    }
                }
            }

            return(true);
        }
Пример #4
0
        /// <summary>
        /// Show the details for the given person.
        /// </summary>
        /// <param name="personGuid"></param>
        private void ShowDetail(Guid personGuid)
        {
            btnReprintLabels.Visible = GetAttributeValue(AttributeKey.AllowLabelReprinting).AsBoolean();

            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);

                var person = personService.Queryable(true, true).Include(a => a.PhoneNumbers).Include(a => a.RecordStatusValue)
                             .FirstOrDefault(a => a.Guid == personGuid);

                if (person == null)
                {
                    return;
                }

                lName.Text = person.FullName;

                string photoTag = Rock.Model.Person.GetPersonPhotoImageTag(person, 200, 200);
                if (person.PhotoId.HasValue)
                {
                    lPhoto.Text = string.Format("<div class='photo'><a href='{0}'>{1}</a></div>", person.PhotoUrl, photoTag);
                }
                else
                {
                    lPhoto.Text = photoTag;
                }

                var campus = person.GetCampus();
                if (campus != null)
                {
                    hlCampus.Visible = true;
                    hlCampus.Text    = campus.Name;
                }
                else
                {
                    hlCampus.Visible = false;
                }

                lGender.Text = person.Gender != Gender.Unknown ? person.Gender.ConvertToString() : "";

                if (person.BirthDate.HasValue)
                {
                    string ageText = (person.BirthYear.HasValue && person.BirthYear != DateTime.MinValue.Year) ?
                                     string.Format("{0} yrs old ", person.BirthDate.Value.Age()) : string.Empty;
                    lAge.Text = string.Format("{0} <small>({1})</small><br/>", ageText, person.BirthDate.Value.ToShortDateString());
                }
                else
                {
                    lAge.Text = string.Empty;
                }

                lGrade.Text = person.GradeFormatted;

                lEmail.Visible = !string.IsNullOrWhiteSpace(person.Email);
                lEmail.Text    = person.GetEmailTag(ResolveRockUrl("/"), "btn btn-default", "<i class='fa fa-envelope'></i>");

                BindAttribute(person);
                // Text Message
                var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.IsMessagingEnabled && n.Number.IsNotNullOrWhiteSpace());
                if (GetAttributeValue(AttributeKey.SMSFrom).IsNotNullOrWhiteSpace() && phoneNumber != null)
                {
                    btnSms.Text          = string.Format("<i class='fa fa-mobile'></i> {0} <small>({1})</small>", phoneNumber.NumberFormatted, phoneNumber.NumberTypeValue);
                    btnSms.Visible       = true;
                    rcwTextMessage.Label = "Text Message";
                }
                else
                {
                    btnSms.Visible       = false;
                    rcwTextMessage.Label = string.Empty;
                }

                // Get all family member from all families ( including self )
                var allFamilyMembers = personService.GetFamilyMembers(person.Id, true).ToList();

                // Add flag for this person in each family indicating if they are a child in family.
                var childGuid     = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
                var isFamilyChild = new Dictionary <int, bool>();
                foreach (var thisPerson in allFamilyMembers.Where(m => m.PersonId == person.Id))
                {
                    isFamilyChild.Add(thisPerson.GroupId, thisPerson.GroupRole.Guid.Equals(childGuid));
                }

                // Get the current url's root (without the person's guid)
                string urlRoot = Request.Url.ToString().ReplaceCaseInsensitive(personGuid.ToString(), "");

                // Get the other family members and the info needed for rendering
                var familyMembers = allFamilyMembers.Where(m => m.PersonId != person.Id)
                                    .OrderBy(m => m.GroupId)
                                    .ThenBy(m => m.Person.BirthDate)
                                    .Select(m => new
                {
                    Url        = urlRoot + m.Person.Guid.ToString(),
                    FullName   = m.Person.FullName,
                    Gender     = m.Person.Gender,
                    FamilyRole = m.GroupRole,
                    Note       = isFamilyChild[m.GroupId] ?
                                 (m.GroupRole.Guid.Equals(childGuid) ? " (Sibling)" : "(Parent)") :
                                 (m.GroupRole.Guid.Equals(childGuid) ? " (Child)" : "")
                })
                                    .ToList();

                rcwFamily.Visible     = familyMembers.Any();
                rptrFamily.DataSource = familyMembers;
                rptrFamily.DataBind();

                rcwRelationships.Visible = false;
                if (GetAttributeValue(AttributeKey.ShowRelatedPeople).AsBoolean())
                {
                    var roles   = new List <int>();
                    var krRoles = new GroupTypeRoleService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(r => r.GroupType.Guid.Equals(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS)))
                                  .ToList();

                    foreach (var role in krRoles)
                    {
                        role.LoadAttributes(rockContext);
                        if (role.GetAttributeValue("CanCheckin").AsBoolean() &&
                            role.Attributes.ContainsKey("InverseRelationship"))
                        {
                            var inverseRoleGuid = role.GetAttributeValue("InverseRelationship").AsGuidOrNull();
                            if (inverseRoleGuid.HasValue)
                            {
                                var inverseRole = krRoles.FirstOrDefault(r => r.Guid == inverseRoleGuid.Value);
                                if (inverseRole != null)
                                {
                                    roles.Add(inverseRole.Id);
                                }
                            }
                        }
                    }

                    if (roles.Any())
                    {
                        var relatedMembers = personService.GetRelatedPeople(new List <int> {
                            person.Id
                        }, roles)
                                             .OrderBy(m => m.Person.LastName)
                                             .ThenBy(m => m.Person.NickName)
                                             .Select(m => new
                        {
                            Url      = urlRoot + m.Person.Guid.ToString(),
                            FullName = m.Person.FullName,
                            Gender   = m.Person.Gender,
                            Note     = " (" + m.GroupRole.Name + ")"
                        })
                                             .ToList();

                        rcwRelationships.Visible     = relatedMembers.Any();
                        rptrRelationships.DataSource = relatedMembers;
                        rptrRelationships.DataBind();
                    }
                }

                var phoneNumbers = person.PhoneNumbers.Where(p => !p.IsUnlisted).ToList();
                rptrPhones.DataSource = phoneNumbers;
                rptrPhones.DataBind();
                rcwPhone.Visible = phoneNumbers.Any();

                var schedules = new ScheduleService(rockContext)
                                .Queryable().AsNoTracking()
                                .Where(s => s.CheckInStartOffsetMinutes.HasValue)
                                .ToList();

                var scheduleIds = schedules.Select(s => s.Id).ToList();

                int?personAliasId = person.PrimaryAliasId;

                PersonAliasService personAliasService = new PersonAliasService(rockContext);
                if (!personAliasId.HasValue)
                {
                    personAliasId = personAliasService.GetPrimaryAliasId(person.Id);
                }

                var attendances = new AttendanceService(rockContext)
                                  .Queryable("Occurrence.Schedule,Occurrence.Group,Occurrence.Location,AttendanceCode")
                                  .Where(a =>
                                         a.PersonAliasId.HasValue &&
                                         a.PersonAliasId == personAliasId &&
                                         a.Occurrence.ScheduleId.HasValue &&
                                         a.Occurrence.GroupId.HasValue &&
                                         a.Occurrence.LocationId.HasValue &&
                                         a.DidAttend.HasValue &&
                                         a.DidAttend.Value &&
                                         scheduleIds.Contains(a.Occurrence.ScheduleId.Value))
                                  .OrderByDescending(a => a.StartDateTime)
                                  .Take(20)
                                  .ToList()                                               // Run query to get recent most 20 checkins
                                  .OrderByDescending(a => a.Occurrence.OccurrenceDate)    // Then sort again by start datetime and schedule start (which is not avail to sql query )
                                  .ThenByDescending(a => a.Occurrence.Schedule.StartTimeOfDay)
                                  .ToList()
                                  .Select(a =>
                {
                    var checkedInByPerson = a.CheckedInByPersonAliasId.HasValue ? personAliasService.GetPerson(a.CheckedInByPersonAliasId.Value) : null;

                    return(new AttendanceInfo
                    {
                        Id = a.Id,
                        Date = a.StartDateTime,
                        GroupId = a.Occurrence.Group.Id,
                        Group = a.Occurrence.Group.Name,
                        LocationId = a.Occurrence.LocationId.Value,
                        Location = a.Occurrence.Location.Name,
                        Schedule = a.Occurrence.Schedule.Name,
                        IsActive = a.IsCurrentlyCheckedIn,
                        Code = a.AttendanceCode != null ? a.AttendanceCode.Code : "",
                        CheckInByPersonName = checkedInByPerson != null ? checkedInByPerson.FullName : string.Empty,
                        CheckInByPersonGuid = checkedInByPerson != null ? checkedInByPerson.Guid : ( Guid? )null
                    });
                }
                                          ).ToList();

                // Set active locations to be a link to the room in manager page
                var qryParam = new Dictionary <string, string>();
                qryParam.Add("Group", "");
                qryParam.Add("Location", "");
                foreach (var attendance in attendances.Where(a => a.IsActive))
                {
                    qryParam["Group"]    = attendance.GroupId.ToString();
                    qryParam["Location"] = attendance.LocationId.ToString();
                    attendance.Location  = string.Format("<a href='{0}'>{1}</a>",
                                                         LinkedPageUrl(AttributeKey.ManagerPage, qryParam), attendance.Location);
                }

                rcwCheckinHistory.Visible = attendances.Any();

                // Get the index of the delete column
                var deleteField = gHistory.Columns.OfType <Rock.Web.UI.Controls.DeleteField>().First();
                _deleteFieldIndex = gHistory.Columns.IndexOf(deleteField);

                gHistory.DataSource = attendances;
                gHistory.DataBind();
            }
        }
Пример #5
0
        /// <summary>
        /// Show the details for the given person.
        /// </summary>
        /// <param name="personGuid"></param>
        private void ShowDetail(Guid personGuid)
        {
            btnReprintLabels.Visible = GetAttributeValue(AttributeKey.AllowLabelReprinting).AsBoolean();

            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);

                var person = personService.Queryable(true, true).Include(a => a.PhoneNumbers).Include(a => a.RecordStatusValue)
                             .FirstOrDefault(a => a.Guid == personGuid);

                if (person == null)
                {
                    return;
                }

                lName.Text = person.FullName;

                string photoTag = Rock.Model.Person.GetPersonPhotoImageTag(person, 200, 200);
                if (person.PhotoId.HasValue)
                {
                    lPhoto.Text = string.Format("<div class='photo'><a href='{0}'>{1}</a></div>", person.PhotoUrl, photoTag);
                }
                else
                {
                    lPhoto.Text = photoTag;
                }

                var campus = person.GetCampus();
                if (campus != null)
                {
                    hlCampus.Visible = true;
                    hlCampus.Text    = campus.Name;
                }
                else
                {
                    hlCampus.Visible = false;
                }

                lGender.Text = person.Gender != Gender.Unknown ?
                               string.Format(@"<div class=""text-semibold text-uppercase"">{0}</div>", person.Gender.ConvertToString().Substring(0, 1)) : string.Empty;

                if (person.BirthDate.HasValue)
                {
                    string ageText = (person.BirthYear.HasValue && person.BirthYear != DateTime.MinValue.Year) ?
                                     string.Format(@"<div class=""text-semibold"">{0}yrs</div>", person.BirthDate.Value.Age()) : string.Empty;
                    lAge.Text = string.Format(@"{0}<div class=""text-sm text-muted"">{1}</div>", ageText, person.BirthDate.Value.ToShortDateString());
                }
                else
                {
                    lAge.Text = string.Empty;
                }

                string   grade      = person.GradeFormatted;
                string[] gradeParts = grade.Split(' ');
                if (gradeParts.Length >= 2)
                {
                    // Note that Grade names might be different in other countries. See  https://separatedbyacommonlanguage.blogspot.com/2006/12/types-of-schools-school-years.html for examples
                    var firstWord      = gradeParts[0];
                    var remainderWords = gradeParts.Skip(1).ToList().AsDelimited(" ");
                    if (firstWord.Equals("Year", StringComparison.OrdinalIgnoreCase))
                    {
                        // MDP 2020-10-21 (at request of GJ)
                        // Special case if formatted grade is 'Year 1', 'Year 2', etc (see https://separatedbyacommonlanguage.blogspot.com/2006/12/types-of-schools-school-years.html)
                        // Make the word Year on the top
                        grade = string.Format(@"<div class=""text-semibold"">{0}</div><div class=""text-sm text-muted"">{1}</div>", remainderWords, firstWord);
                    }
                    else
                    {
                        grade = string.Format(@"<div class=""text-semibold"">{0}</div><div class=""text-sm text-muted"">{1}</div>", firstWord, remainderWords);
                    }
                }

                lGrade.Text = grade;

                lEmail.Visible = !string.IsNullOrWhiteSpace(person.Email);
                lEmail.Text    = string.Format(@"<div class=""text-truncate"">{0}</div>", person.GetEmailTag(ResolveRockUrl("/"), "text-color"));

                BindAttribute(person);

                // Text Message
                var phoneNumber = person.PhoneNumbers.FirstOrDefault(n => n.IsMessagingEnabled && n.Number.IsNotNullOrWhiteSpace());
                if (GetAttributeValue(AttributeKey.SMSFrom).IsNotNullOrWhiteSpace() && phoneNumber != null)
                {
                    SmsPhoneNumberId = phoneNumber.Id;
                }
                else
                {
                    SmsPhoneNumberId = 0;
                }

                // Get all family member from all families ( including self )
                var allFamilyMembers = personService.GetFamilyMembers(person.Id, true).ToList();

                // Add flag for this person in each family indicating if they are a child in family.
                var childGuid     = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
                var isFamilyChild = new Dictionary <int, bool>();
                foreach (var thisPerson in allFamilyMembers.Where(m => m.PersonId == person.Id))
                {
                    isFamilyChild.Add(thisPerson.GroupId, thisPerson.GroupRole.Guid.Equals(childGuid));
                }

                // Get the other family members and the info needed for rendering
                var familyMembers = allFamilyMembers.Where(m => m.PersonId != person.Id)
                                    .OrderBy(m => m.GroupId)
                                    .ThenBy(m => m.Person.BirthDate)
                                    .Select(m => new PersonInfo
                {
                    PhotoTag = Rock.Model.Person.GetPersonPhotoImageTag(m.Person, 64, 64, className: "d-block mb-1"),
                    Url      = GetRelatedPersonUrl(person, m.Person.Guid, m.Person.Id),
                    NickName = m.Person.NickName,
                    //FullName = m.Person.FullName,
                    //Gender = m.Person.Gender,
                    //FamilyRole = m.GroupRole,
                    //Note = isFamilyChild[m.GroupId] ?
                    //    ( m.GroupRole.Guid.Equals( childGuid ) ? " (Sibling)" : "(Parent)" ) :
                    //    ( m.GroupRole.Guid.Equals( childGuid ) ? " (Child)" : "" )
                })
                                    .ToList();

                pnlFamily.Visible     = familyMembers.Any();
                rptrFamily.DataSource = familyMembers;
                rptrFamily.DataBind();

                pnlRelationships.Visible = false;
                if (GetAttributeValue(AttributeKey.ShowRelatedPeople).AsBoolean())
                {
                    var roles   = new List <int>();
                    var krRoles = new GroupTypeRoleService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(r => r.GroupType.Guid.Equals(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS)))
                                  .ToList();

                    foreach (var role in krRoles)
                    {
                        role.LoadAttributes(rockContext);
                        if (role.GetAttributeValue("CanCheckin").AsBoolean() &&
                            role.Attributes.ContainsKey("InverseRelationship"))
                        {
                            var inverseRoleGuid = role.GetAttributeValue("InverseRelationship").AsGuidOrNull();
                            if (inverseRoleGuid.HasValue)
                            {
                                var inverseRole = krRoles.FirstOrDefault(r => r.Guid == inverseRoleGuid.Value);
                                if (inverseRole != null)
                                {
                                    roles.Add(inverseRole.Id);
                                }
                            }
                        }
                    }

                    if (roles.Any())
                    {
                        var relatedMembers = personService.GetRelatedPeople(new List <int> {
                            person.Id
                        }, roles)
                                             .OrderBy(m => m.Person.LastName)
                                             .ThenBy(m => m.Person.NickName)
                                             .Select(m => new PersonInfo
                        {
                            PhotoTag = Rock.Model.Person.GetPersonPhotoImageTag(m.Person, 50, 50, className: "rounded"),
                            Url      = GetRelatedPersonUrl(person, m.Person.Guid, m.Person.Id),
                            NickName = m.Person.NickName,
                            //FullName = m.Person.FullName,
                            //Gender = m.Person.Gender,
                            //Note = " (" + m.GroupRole.Name + ")"
                        })
                                             .ToList();

                        pnlRelationships.Visible     = relatedMembers.Any();
                        rptrRelationships.DataSource = relatedMembers;
                        rptrRelationships.DataBind();
                    }
                }

                var phoneNumbers = person.PhoneNumbers.Where(p => !p.IsUnlisted).ToList();
                rptrPhones.DataSource = phoneNumbers;
                rptrPhones.DataBind();
                pnlContact.Visible = phoneNumbers.Any() || lEmail.Visible;

                var schedules = new ScheduleService(rockContext)
                                .Queryable().AsNoTracking()
                                .Where(s => s.CheckInStartOffsetMinutes.HasValue)
                                .ToList();

                var scheduleIds = schedules.Select(s => s.Id).ToList();

                var personAliasIds = person.Aliases.Select(a => a.Id).ToList();

                PersonAliasService personAliasService = new PersonAliasService(rockContext);

                var attendances = new AttendanceService(rockContext)
                                  .Queryable("Occurrence.Schedule,Occurrence.Group,Occurrence.Location,AttendanceCode")
                                  .Where(a =>
                                         a.PersonAliasId.HasValue &&
                                         personAliasIds.Contains(a.PersonAliasId.Value) &&
                                         a.Occurrence.ScheduleId.HasValue &&
                                         a.Occurrence.GroupId.HasValue &&
                                         a.Occurrence.LocationId.HasValue &&
                                         a.DidAttend.HasValue &&
                                         a.DidAttend.Value &&
                                         scheduleIds.Contains(a.Occurrence.ScheduleId.Value))
                                  .OrderByDescending(a => a.StartDateTime)
                                  .Take(20)
                                  .ToList()                                               // Run query to get recent most 20 checkins
                                  .OrderByDescending(a => a.Occurrence.OccurrenceDate)    // Then sort again by start datetime and schedule start (which is not avail to sql query )
                                  .ThenByDescending(a => a.Occurrence.Schedule.StartTimeOfDay)
                                  .ToList()
                                  .Select(a =>
                {
                    var checkedInByPerson = a.CheckedInByPersonAliasId.HasValue ? personAliasService.GetPerson(a.CheckedInByPersonAliasId.Value) : null;

                    return(new AttendanceInfo
                    {
                        Id = a.Id,
                        Date = a.StartDateTime,
                        GroupId = a.Occurrence.Group.Id,
                        GroupName = a.Occurrence.Group.Name,
                        LocationId = a.Occurrence.LocationId.Value,
                        LocationName = a.Occurrence.Location.Name,
                        ScheduleName = a.Occurrence.Schedule.Name,
                        IsActive = a.IsCurrentlyCheckedIn,
                        Code = a.AttendanceCode != null ? a.AttendanceCode.Code : "",
                        CheckInByPersonName = checkedInByPerson != null ? checkedInByPerson.FullName : string.Empty,
                        CheckInByPersonGuid = checkedInByPerson != null ? checkedInByPerson.Guid : ( Guid? )null
                    });
                }
                                          ).ToList();

                // Set active locations to be a link to the room in manager page
                var qryParams = new Dictionary <string, string>
                {
                    { PageParameterKey.LocationId, string.Empty }
                };

                // If an Area Guid was passed to the Page, pass it back.
                string areaGuid = PageParameter(PageParameterKey.AreaGuid);
                if (areaGuid.IsNotNullOrWhiteSpace())
                {
                    qryParams.Add(PageParameterKey.AreaGuid, areaGuid);
                }

                foreach (var attendance in attendances)
                {
                    if (attendance.IsActive)
                    {
                        qryParams[PageParameterKey.LocationId] = attendance.LocationId.ToString();
                        attendance.LocationNameHtml            = string.Format(
                            "<a href='{0}'>{1}</a>",
                            LinkedPageUrl(AttributeKey.ManagerPage, qryParams),
                            attendance.LocationName);
                    }
                    else
                    {
                        attendance.LocationNameHtml = attendance.LocationName;
                    }
                }

                pnlCheckinHistory.Visible = attendances.Any();

                // Get the index of the delete column
                var deleteField = gHistory.Columns.OfType <Rock.Web.UI.Controls.DeleteField>().First();
                _deleteFieldIndex = gHistory.Columns.IndexOf(deleteField);

                gHistory.DataSource = attendances;
                gHistory.DataBind();
            }
        }
Пример #6
0
        /// <summary>
        /// Show the details for the given person.
        /// </summary>
        /// <param name="personGuid"></param>
        private void ShowDetail(Guid personGuid)
        {
            btnReprintLabels.Visible = GetAttributeValue(AttributeKey.AllowLabelReprinting).AsBoolean() && this.IsUserAuthorized(SecurityActionKey.ReprintLabels);

            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);

                var person = personService.Queryable(true, true).Include(a => a.PhoneNumbers).Include(a => a.RecordStatusValue)
                             .FirstOrDefault(a => a.Guid == personGuid);

                if (person == null)
                {
                    return;
                }

                lGender.Text = person.Gender != Gender.Unknown ?
                               string.Format(@"<div class=""text-semibold text-uppercase"">{0}</div>", person.Gender.ConvertToString().Substring(0, 1)) : string.Empty;

                if (person.BirthDate.HasValue)
                {
                    string ageText = (person.BirthYear.HasValue && person.BirthYear != DateTime.MinValue.Year) ?
                                     string.Format(@"<div class=""text-semibold"">{0}yrs</div>", person.BirthDate.Value.Age()) : string.Empty;
                    lAge.Text = string.Format(@"{0}<div class=""text-sm text-muted"">{1}</div>", ageText, person.BirthDate.Value.ToShortDateString());
                }
                else
                {
                    lAge.Text = string.Empty;
                }

                string   grade      = person.GradeFormatted;
                string[] gradeParts = grade.Split(' ');
                if (gradeParts.Length >= 2)
                {
                    // Note that Grade names might be different in other countries.
                    // See  https://separatedbyacommonlanguage.blogspot.com/2006/12/types-of-schools-school-years.html for examples.
                    var firstWord      = gradeParts[0];
                    var remainderWords = gradeParts.Skip(1).ToList().AsDelimited(" ");
                    if (firstWord.Equals("Year", StringComparison.OrdinalIgnoreCase))
                    {
                        // MDP 2020-10-21 (at request of GJ)
                        // Special case if formatted grade is 'Year 1', 'Year 2', etc (see https://separatedbyacommonlanguage.blogspot.com/2006/12/types-of-schools-school-years.html)
                        // Make the word Year on the top.
                        grade = string.Format(@"<div class=""text-semibold"">{0}</div><div class=""text-sm text-muted"">{1}</div>", remainderWords, firstWord);
                    }
                    else
                    {
                        grade = string.Format(@"<div class=""text-semibold"">{0}</div><div class=""text-sm text-muted"">{1}</div>", firstWord, remainderWords);
                    }
                }

                lGrade.Text = grade;

                var schedules = new ScheduleService(rockContext)
                                .Queryable().AsNoTracking()
                                .Where(s => s.CheckInStartOffsetMinutes.HasValue)
                                .ToList();

                var scheduleIds = schedules.Select(s => s.Id).ToList();

                var personAliasIds = person.Aliases.Select(a => a.Id).ToList();

                PersonAliasService personAliasService = new PersonAliasService(rockContext);

                var attendances = new AttendanceService(rockContext)
                                  .Queryable("Occurrence.Schedule,Occurrence.Group,Occurrence.Location,AttendanceCode")
                                  .Where(a =>
                                         a.PersonAliasId.HasValue &&
                                         personAliasIds.Contains(a.PersonAliasId.Value) &&
                                         a.Occurrence.ScheduleId.HasValue &&
                                         a.Occurrence.GroupId.HasValue &&
                                         a.Occurrence.LocationId.HasValue &&
                                         a.DidAttend.HasValue &&
                                         a.DidAttend.Value &&
                                         scheduleIds.Contains(a.Occurrence.ScheduleId.Value))
                                  .OrderByDescending(a => a.StartDateTime)
                                  .Take(20)
                                  .ToList()                                               // Run query to get recent most 20 checkins
                                  .OrderByDescending(a => a.Occurrence.OccurrenceDate)    // Then sort again by start datetime and schedule start (which is not avail to sql query )
                                  .ThenByDescending(a => a.Occurrence.Schedule.StartTimeOfDay)
                                  .ToList()
                                  .Select(a =>
                {
                    var checkedInByPerson = a.CheckedInByPersonAliasId.HasValue ? personAliasService.GetPerson(a.CheckedInByPersonAliasId.Value) : null;

                    return(new AttendanceInfo
                    {
                        Id = a.Id,
                        Date = a.StartDateTime,
                        GroupId = a.Occurrence.Group.Id,
                        GroupName = a.Occurrence.Group.Name,
                        LocationId = a.Occurrence.LocationId.Value,
                        LocationName = a.Occurrence.Location.Name,
                        ScheduleName = a.Occurrence.Schedule.Name,
                        IsActive = a.IsCurrentlyCheckedIn,
                        Code = a.AttendanceCode != null ? a.AttendanceCode.Code : string.Empty,
                        CheckInByPersonName = checkedInByPerson != null ? checkedInByPerson.FullName : string.Empty,
                        CheckInByPersonGuid = checkedInByPerson != null ? checkedInByPerson.Guid : ( Guid? )null
                    });
                }).ToList();

                // Set active locations to be a link to the room in manager page.
                var qryParams = new Dictionary <string, string>
                {
                    { PageParameterKey.LocationId, string.Empty }
                };

                // If an Area Guid was passed to the Page, pass it back.
                string areaGuid = PageParameter(PageParameterKey.AreaGuid);
                if (areaGuid.IsNotNullOrWhiteSpace())
                {
                    qryParams.Add(PageParameterKey.AreaGuid, areaGuid);
                }

                foreach (var attendance in attendances)
                {
                    if (attendance.IsActive)
                    {
                        qryParams[PageParameterKey.LocationId] = attendance.LocationId.ToString();
                        attendance.LocationNameHtml            = string.Format(
                            "<a href='{0}'>{1}</a>",
                            LinkedPageUrl(AttributeKey.ManagerPage, qryParams),
                            attendance.LocationName);
                    }
                    else
                    {
                        attendance.LocationNameHtml = attendance.LocationName;
                    }
                }

                pnlCheckinHistory.Visible = attendances.Any();

                gAttendanceHistory.DataSource = attendances;
                gAttendanceHistory.DataBind();
            }
        }
Пример #7
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The workflow action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override bool Execute(RockContext rockContext, Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null && checkInState.CheckInType.TypeOfCheckin == TypeOfCheckin.Family)
            {
                bool configPrevents = checkInState.CheckInType.PreventDuplicateCheckin;

                var family = checkInState.CheckIn.CurrentFamily;

                if (family != null)
                {
                    var remove = GetAttributeValue(action, "Remove").AsBoolean();

                    var personIds = family.People.Select(p => p.Person.Id).ToList();
                    var today     = RockDateTime.Today;
                    var tomorrow  = RockDateTime.Today.AddDays(1);

                    var existingAttendance = new AttendanceService(rockContext)
                                             .Queryable().AsNoTracking()
                                             .Where(a =>
                                                    a.StartDateTime.CompareTo(today) >= 0 &&
                                                    a.StartDateTime.CompareTo(tomorrow) < 0 &&
                                                    a.DidAttend.HasValue &&
                                                    a.DidAttend.Value &&
                                                    a.PersonAlias != null &&
                                                    personIds.Contains(a.PersonAlias.PersonId) &&
                                                    a.ScheduleId.HasValue)
                                             .Select(a => new
                    {
                        PersonId   = a.PersonAlias.PersonId,
                        ScheduleId = a.ScheduleId.Value
                    })
                                             .ToList();

                    if (existingAttendance.Any())
                    {
                        foreach (var person in family.People.ToList())
                        {
                            var attendedScheduleIds = existingAttendance.Where(a => a.PersonId == person.Person.Id).Select(a => a.ScheduleId).ToList();
                            if (attendedScheduleIds.Any())
                            {
                                foreach (var groupType in person.GroupTypes.ToList())
                                {
                                    if (configPrevents || groupType.GroupType.GetAttributeValue("PreventDuplicateCheckin").AsBoolean())
                                    {
                                        attendedScheduleIds.ForEach(s => groupType.AvailableForSchedule.Remove(s));

                                        if (!groupType.AvailableForSchedule.Any())
                                        {
                                            person.GroupTypes.Remove(groupType);
                                        }
                                        else
                                        {
                                            foreach (var group in groupType.Groups.ToList())
                                            {
                                                attendedScheduleIds.ForEach(s => group.AvailableForSchedule.Remove(s));
                                                if (!group.AvailableForSchedule.Any())
                                                {
                                                    groupType.Groups.Remove(group);
                                                }
                                                else
                                                {
                                                    foreach (var location in group.Locations.ToList())
                                                    {
                                                        attendedScheduleIds.ForEach(s => location.AvailableForSchedule.Remove(s));
                                                        if (!location.AvailableForSchedule.Any())
                                                        {
                                                            group.Locations.Remove(location);
                                                        }
                                                    }
                                                    if (group.Locations.Count == 0)
                                                    {
                                                        groupType.Groups.Remove(group);
                                                    }
                                                }
                                            }
                                            if (groupType.Groups.Count == 0)
                                            {
                                                person.GroupTypes.Remove(groupType);
                                            }
                                        }
                                    }
                                }

                                if (person.GroupTypes.Count == 0)
                                {
                                    family.People.Remove(person);
                                }
                            }
                        }
                    }
                }

                return(true);
            }

            return(false);
        }