/// <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) { AttendanceCode attendanceCode = null; bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode; int securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3; int securityCodeAlphaLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0; int securityCodeNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0; bool securityCodeNumericRandom = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true; var attendanceCodeService = new AttendanceCodeService(rockContext); var attendanceService = new AttendanceService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var personAliasService = new PersonAliasService(rockContext); var family = checkInState.CheckIn.CurrentFamily; if (family != null) { foreach (var person in family.GetPeople(true)) { if (reuseCodeForFamily && attendanceCode != null) { person.SecurityCode = attendanceCode.Code; } else { attendanceCode = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom); person.SecurityCode = attendanceCode.Code; } foreach (var groupType in person.GetGroupTypes(true)) { foreach (var group in groupType.GetGroups(true)) { if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn && groupType.GroupType.DefaultGroupRoleId.HasValue && !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any()) { var groupMember = new GroupMember(); groupMember.GroupId = group.Group.Id; groupMember.PersonId = person.Person.Id; groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value; groupMemberService.Add(groupMember); } foreach (var location in group.GetLocations(true)) { foreach (var schedule in location.GetSchedules(true)) { var startDateTime = schedule.CampusCurrentDateTime; // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id); if (primaryAlias != null) { attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, group.Group.Id, location.Location.Id, schedule.Schedule.Id, location.CampusId, checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id, checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id); attendance.PersonAlias = primaryAlias; } } attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id; attendance.SearchValue = checkInState.CheckIn.SearchValue; attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId; attendance.SearchResultGroupId = family.Group.Id; attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; attendance.Note = group.Notes; KioskLocationAttendance.AddAttendance(attendance); } } } } } } rockContext.SaveChanges(); return(true); } return(false); }
/// <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) { Guid checkinGroupAttributeGuid = GetAttributeValue(action, "CheckinGroupAttribute").AsGuid(); if (checkinGroupAttributeGuid == Guid.Empty) { throw new Exception("CheckInGroupAttribute not set. Set attribute to continue."); } string checkinGroupAttributeKey = AttributeCache.Read(checkinGroupAttributeGuid, rockContext).Key; string sessionAttributeKey = GetAttributeValue(action, "SessionAttributeKey"); AttendanceCode attendanceCode = null; DateTime startDateTime = RockDateTime.Now; bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode; int securityCodeLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3; AttendanceCodeService attendanceCodeService = new AttendanceCodeService(rockContext); AttendanceService attendanceService = new AttendanceService(rockContext); GroupMemberService groupMemberService = new GroupMemberService(rockContext); PersonAliasService personAliasService = new PersonAliasService(rockContext); GroupService groupService = new GroupService(rockContext); var family = checkInState.CheckIn.CurrentFamily; if (family != null) { foreach (var person in family.GetPeople(true)) { if (reuseCodeForFamily && attendanceCode != null) { person.SecurityCode = attendanceCode.Code; } else { attendanceCode = AttendanceCodeService.GetNew(securityCodeLength); person.SecurityCode = attendanceCode.Code; } foreach (var groupType in person.GetGroupTypes(true)) { foreach (var group in groupType.GetGroups(true)) { var referenceGroupGuid = group.Group.GetAttributeValue(checkinGroupAttributeKey).AsGuid(); var referenceGroup = groupService.Get(referenceGroupGuid); if (referenceGroup == null) { group.Selected = false; continue; } GroupMember groupMember = groupMemberService.GetByGroupIdAndPersonId(referenceGroup.Id, person.Person.Id).FirstOrDefault(); if (groupMember == null) { group.Selected = false; continue; } groupMember.LoadAttributes(); int sessions = groupMember.GetAttributeValue(sessionAttributeKey).AsInteger(); foreach (var location in group.GetLocations(true)) { foreach (var schedule in location.GetSchedules(true)) { if (sessions == 0) { continue; } // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id); if (primaryAlias != null) { attendance = rockContext.Attendances.Create(); attendance.LocationId = location.Location.Id; attendance.CampusId = location.CampusId; attendance.ScheduleId = schedule.Schedule.Id; attendance.GroupId = group.Group.Id; attendance.PersonAlias = primaryAlias; attendance.PersonAliasId = primaryAlias.Id; attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id; attendanceService.Add(attendance); } //decrement sessions and save sessions--; groupMember.SetAttributeValue(sessionAttributeKey, sessions); groupMember.SaveAttributeValues(); } else { foreach (var cPerson in checkInState.CheckIn.Families.SelectMany(f => f.People)) { cPerson.Selected = false; cPerson.GroupTypes.ForEach(gt => gt.Selected = false); } return(true); } attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; KioskLocationAttendance.AddAttendance(attendance); } } } } } } rockContext.SaveChanges(); return(true); } return(false); }
/// <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> public override bool Execute(RockContext rockContext, Model.WorkflowAction action, object entity, out List <string> errorMessages) { var checkInState = GetCheckInState(entity, out errorMessages); if (checkInState == null) { return(false); } AttendanceCode attendanceCode = null; bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode; int securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3; int securityCodeAlphaLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0; int securityCodeNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0; bool securityCodeNumericRandom = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true; bool enablePresence = checkInState.CheckInType != null && checkInState.CheckInType.EnablePresence; var attendanceCodeService = new AttendanceCodeService(rockContext); var attendanceService = new AttendanceService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var personAliasService = new PersonAliasService(rockContext); var attendanceRecords = new List <Attendance>(); AttendanceCheckInSession attendanceCheckInSession = new AttendanceCheckInSession() { DeviceId = checkInState.DeviceId, ClientIpAddress = RockPage.GetClientIpAddress() }; checkInState.Messages.Clear(); var family = checkInState.CheckIn.CurrentFamily; if (family != null) { var currentOccurrences = new List <OccurrenceRecord>(); foreach (var person in family.GetPeople(true)) { if (reuseCodeForFamily && attendanceCode != null) { person.SecurityCode = attendanceCode.Code; } else { attendanceCode = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom); person.SecurityCode = attendanceCode.Code; } foreach (var groupType in person.GetGroupTypes(true)) { foreach (var group in groupType.GetGroups(true)) { if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn && groupType.GroupType.DefaultGroupRoleId.HasValue && !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any()) { var groupMember = new GroupMember(); groupMember.GroupId = group.Group.Id; groupMember.PersonId = person.Person.Id; groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value; groupMemberService.Add(groupMember); } foreach (var location in group.GetLocations(true)) { bool isCheckedIntoLocation = false; foreach (var schedule in location.GetSchedules(true)) { var startDateTime = schedule.CampusCurrentDateTime; // If we're enforcing strict location thresholds, then before we create an attendance record // we need to check the location-schedule's current count. if (GetAttributeValue(action, AttributeKey.EnforceStrictLocationThreshold).AsBoolean() && location.Location.SoftRoomThreshold.HasValue) { EnforceStrictLocationThreshold(action, checkInState, attendanceService, currentOccurrences, person, group, location, schedule, startDateTime); } // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id); if (primaryAlias != null) { attendance = attendanceService.AddOrUpdate( primaryAlias.Id, startDateTime.Date, group.Group.Id, location.Location.Id, schedule.Schedule.Id, location.CampusId, checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType?.Id, checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id); attendance.PersonAlias = primaryAlias; } } attendance.AttendanceCheckInSession = attendanceCheckInSession; attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType?.Id; attendance.SearchValue = checkInState.CheckIn.SearchValue; attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId; attendance.SearchResultGroupId = family.Group.Id; attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.CheckedOutByPersonAliasId = null; attendance.DidAttend = true; attendance.Note = group.Notes; attendance.IsFirstTime = person.FirstTime; /* * 7/16/2020 - JH * If EnablePresence is true for this Check-in configuration, it will be the responsibility of the room * attendants to mark a given Person as present, so do not set the 'Present..' property values below. * Otherwise, set the values to match those of the Check-in values: the Person checking them in will * have simultaneously marked them as present. * * Also, note that we sometimes reuse Attendance records (i.e. the Person was already checked into this * schedule/group/location, might have already been checked out, and also might have been previously * marked as present). In this case, the same 'Present..' rules apply, but we might need to go so far * as to null-out the previously set 'Present..' property values, hence the conditional operators below. */ attendance.PresentDateTime = enablePresence ? ( DateTime? )null : startDateTime; attendance.PresentByPersonAliasId = enablePresence ? null : checkInState.CheckIn.CheckedInByPersonAliasId; KioskLocationAttendance.AddAttendance(attendance); isCheckedIntoLocation = true; // Keep track of attendance (Ids) for use by other actions later in the workflow pipeline attendanceRecords.Add(attendance); } // If the person was NOT checked into the location for any schedule then remove the location if (!isCheckedIntoLocation) { group.Locations.Remove(location); } } } } } } if (checkInState.CheckInType.AchievementTypes.Any()) { // Get any achievements that were in-progress *prior* to adding these attendance records var configuredAchievementTypeIds = checkInState.CheckInType.AchievementTypes.Select(a => a.Id).ToList(); var attendanceRecordsPersonAliasIds = attendanceRecords.Where(a => a.PersonAliasId.HasValue).Select(a => a.PersonAliasId.Value).ToArray(); var successfullyCompletedAchievementsPriorToSaveChanges = GetSuccessfullyCompletedAchievementAttempts(rockContext, attendanceRecordsPersonAliasIds, configuredAchievementTypeIds); rockContext.SaveChanges(); AchievementAttemptService.AchievementAttemptWithPersonAlias[] achievementAttemptsAfterSaveChanges = GetAchievementAttemptsWithPersonAliasQuery(rockContext, attendanceRecordsPersonAliasIds, configuredAchievementTypeIds).AsNoTracking().ToArray(); checkInState.CheckIn.SuccessfullyCompletedAchievementsPriorToCheckin = successfullyCompletedAchievementsPriorToSaveChanges; checkInState.CheckIn.AchievementsStateAfterCheckin = achievementAttemptsAfterSaveChanges; } else { rockContext.SaveChanges(); } // Now that the records are persisted, take the Ids and save them to the temp CheckInFamliy object family.AttendanceIds = attendanceRecords.Select(a => a.Id).ToList(); family.AttendanceCheckinSessionGuid = attendanceCheckInSession.Guid; attendanceRecords = null; return(true); }
/// <summary> /// Executes the specified workflow. /// </summary> /// <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(Model.WorkflowAction action, Object entity, out List <string> errorMessages) { var checkInState = GetCheckInState(entity, out errorMessages); if (checkInState != null) { DateTime startDateTime = DateTime.Now; int securityCodeLength = 3; if (!int.TryParse(GetAttributeValue(action, "SecurityCodeLength"), out securityCodeLength)) { securityCodeLength = 3; } using (var uow = new Rock.Data.UnitOfWorkScope()) { var attendanceCodeService = new AttendanceCodeService(); var attendanceService = new AttendanceService(); var groupMemberService = new GroupMemberService(); foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected)) { foreach (var person in family.People.Where(p => p.Selected)) { var attendanceCode = attendanceCodeService.GetNew(securityCodeLength); person.SecurityCode = attendanceCode.Code; foreach (var groupType in person.GroupTypes.Where(g => g.Selected)) { foreach (var group in groupType.Groups.Where(g => g.Selected)) { foreach (var location in group.Locations.Where(l => l.Selected)) { if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn && groupType.GroupType.DefaultGroupRoleId.HasValue && !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any()) { var groupMember = new GroupMember(); groupMember.GroupId = group.Group.Id; groupMember.PersonId = person.Person.Id; groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value; groupMemberService.Add(groupMember, null); groupMemberService.Save(groupMember, null); } foreach (var schedule in location.Schedules.Where(s => s.Selected)) { // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { attendance = ((Rock.Data.RockContext)uow.DbContext).Attendances.Create(); attendance.LocationId = location.Location.Id; attendance.ScheduleId = schedule.Schedule.Id; attendance.GroupId = group.Group.Id; attendance.PersonId = person.Person.Id; attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id; attendanceService.Add(attendance, null); } attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; attendanceService.Save(attendance, null); KioskLocationAttendance.AddAttendance(attendance); } } } } } } } return(true); } return(false); }
/// <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) { AttendanceCode attendanceCode = null; DateTime startDateTime = RockDateTime.Now; bool reuseCodeForFamily = GetAttributeValue(action, "ReuseCodeForFamily").AsBoolean(); int securityCodeLength = 3; if (!int.TryParse(GetAttributeValue(action, "SecurityCodeLength"), out securityCodeLength)) { securityCodeLength = 3; } var attendanceCodeService = new AttendanceCodeService(rockContext); var attendanceService = new AttendanceService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var personAliasService = new PersonAliasService(rockContext); foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected)) { foreach (var person in family.People.Where(p => p.Selected)) { if (reuseCodeForFamily && attendanceCode != null) { person.SecurityCode = attendanceCode.Code; } else { attendanceCode = AttendanceCodeService.GetNew(securityCodeLength); person.SecurityCode = attendanceCode.Code; } foreach (var groupType in person.GroupTypes.Where(g => g.Selected)) { foreach (var group in groupType.Groups.Where(g => g.Selected)) { foreach (var location in group.Locations.Where(l => l.Selected)) { if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn && groupType.GroupType.DefaultGroupRoleId.HasValue && !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any()) { var groupMember = new GroupMember(); groupMember.GroupId = group.Group.Id; groupMember.PersonId = person.Person.Id; groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value; groupMemberService.Add(groupMember); } foreach (var schedule in location.Schedules.Where(s => s.Selected)) { // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id); if (primaryAlias != null) { attendance = rockContext.Attendances.Create(); attendance.Occurrence.LocationId = location.Location.Id; attendance.CampusId = location.CampusId; attendance.Occurrence.ScheduleId = schedule.Schedule.Id; attendance.Occurrence.GroupId = group.Group.Id; attendance.PersonAlias = primaryAlias; attendance.PersonAliasId = primaryAlias.Id; attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id; attendanceService.Add(attendance); } } attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = false; KioskLocationAttendance.AddAttendance(attendance); } } } } } } rockContext.SaveChanges(); return(true); } errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null."); return(false); }
/// <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) { AttendanceCode attendanceCode = null; bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode; int securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3; int securityCodeAlphaLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0; int securityCodeNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0; bool securityCodeNumericRandom = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true; var attendanceCodeService = new AttendanceCodeService(rockContext); var attendanceService = new AttendanceService(rockContext); var groupMemberService = new GroupMemberService(rockContext); var personAliasService = new PersonAliasService(rockContext); var attendanceRecords = new List <Attendance>(); checkInState.Messages.Clear(); var family = checkInState.CheckIn.CurrentFamily; if (family != null) { var currentOccurences = new List <OccurenceRecord>(); foreach (var person in family.GetPeople(true)) { if (reuseCodeForFamily && attendanceCode != null) { person.SecurityCode = attendanceCode.Code; } else { attendanceCode = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom); person.SecurityCode = attendanceCode.Code; } foreach (var groupType in person.GetGroupTypes(true)) { foreach (var group in groupType.GetGroups(true)) { if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn && groupType.GroupType.DefaultGroupRoleId.HasValue && !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any()) { var groupMember = new GroupMember(); groupMember.GroupId = group.Group.Id; groupMember.PersonId = person.Person.Id; groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value; groupMemberService.Add(groupMember); } foreach (var location in group.GetLocations(true)) { bool isCheckedIntoLocation = false; foreach (var schedule in location.GetSchedules(true)) { var startDateTime = schedule.CampusCurrentDateTime; // If we're enforcing strict location thresholds, then before we create an attendance record // we need to check the location-schedule's current count. if (GetAttributeValue(action, "EnforceStrictLocationThreshold").AsBoolean() && location.Location.SoftRoomThreshold.HasValue) { var thresHold = location.Location.SoftRoomThreshold.Value; if (checkInState.ManagerLoggedIn && location.Location.FirmRoomThreshold.HasValue && location.Location.FirmRoomThreshold.Value > location.Location.SoftRoomThreshold.Value) { thresHold = location.Location.FirmRoomThreshold.Value; } var currentOccurence = GetCurrentOccurence(currentOccurences, location, schedule, startDateTime.Date); // The totalAttended is the number of people still checked in (not people who have been checked-out) // not counting the current person who may already be checked in, // + the number of people we have checked in so far (but haven't been saved yet). var attendanceQry = attendanceService.GetByDateOnLocationAndSchedule(startDateTime.Date, location.Location.Id, schedule.Schedule.Id) .AsNoTracking() .Where(a => a.EndDateTime == null); // Only process if the current person is NOT already checked-in to this location and schedule if (!attendanceQry.Where(a => a.PersonAlias.PersonId == person.Person.Id).Any()) { var totalAttended = attendanceQry.Count() + (currentOccurence == null ? 0 : currentOccurence.Count); // If over capacity, remove the schedule and add a warning message. if (totalAttended >= thresHold) { // Remove the schedule since the location was full for this schedule. location.Schedules.Remove(schedule); var message = new CheckInMessage() { MessageType = MessageType.Warning }; var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Person", person.Person); mergeFields.Add("Group", group.Group); mergeFields.Add("Location", location.Location); mergeFields.Add("Schedule", schedule.Schedule); message.MessageText = GetAttributeValue(action, "NotChecked-InMessageFormat").ResolveMergeFields(mergeFields); // Now add it to the check-in state message list for others to see. checkInState.Messages.Add(message); continue; } else { // Keep track of anyone who was checked in so far. if (currentOccurence == null) { currentOccurence = new OccurenceRecord() { Date = startDateTime.Date, LocationId = location.Location.Id, ScheduleId = schedule.Schedule.Id }; currentOccurences.Add(currentOccurence); } currentOccurence.Count += 1; } } } // Only create one attendance record per day for each person/schedule/group/location var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id); if (attendance == null) { var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id); if (primaryAlias != null) { attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, group.Group.Id, location.Location.Id, schedule.Schedule.Id, location.CampusId, checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id, checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id); attendance.PersonAlias = primaryAlias; } } attendance.DeviceId = checkInState.Kiosk.Device.Id; attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id; attendance.SearchValue = checkInState.CheckIn.SearchValue; attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId; attendance.SearchResultGroupId = family.Group.Id; attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; attendance.Note = group.Notes; KioskLocationAttendance.AddAttendance(attendance); isCheckedIntoLocation = true; // Keep track of attendance (Ids) for use by other actions later in the workflow pipeline attendanceRecords.Add(attendance); } // If the person was NOT checked into the location for any schedule then remove the location if (!isCheckedIntoLocation) { group.Locations.Remove(location); } } } } } } rockContext.SaveChanges(); // Now that the records are persisted, take the Ids and save them to the temp CheckInFamliy object family.AttendanceIds = attendanceRecords.Select(a => a.Id).ToList(); attendanceRecords = null; return(true); } return(false); }