/// <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()); }
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(); } } }
/// <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); }
/// <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(); } }
/// <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(); } }
/// <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(); } }
/// <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); }