/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode"/> /// </summary> /// <param name="codeLength">A <see cref="System.Int32"/> representing the length of the (security) code.</param> /// <returns>A new <see cref="Rock.Model.AttendanceCode"/></returns> public static AttendanceCode GetNew(int codeLength = 3) { string code = string.Empty; var attendanceCode = new AttendanceCode(); var rockContext = new Rock.Data.RockContext(); var service = new AttendanceCodeService( rockContext ); // Make sure only one instance at a time is checking for unique code lock (obj) { // Find a good unique code for today while ( code == string.Empty || noGood.Any( s => s == code ) || service.Get( RockDateTime.Today, code ).Any() ) { code = GenerateRandomCode( codeLength ); } attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add( attendanceCode ); rockContext.SaveChanges(); } return attendanceCode; }
/// <summary> /// Gets the new. /// </summary> /// <param name="alphaNumericLength">Length of the alpha numeric.</param> /// <param name="alphaLength">Length of the alpha.</param> /// <param name="numericLength">Length of the numeric.</param> /// <param name="isRandomized">if set to <c>true</c> [is randomized].</param> /// <returns></returns> public static AttendanceCode GetNew(int alphaNumericLength, int alphaLength, int numericLength, bool isRandomized) { lock ( _obj ) { using (var rockContext = new Rock.Data.RockContext()) { var service = new AttendanceCodeService(rockContext); DateTime today = RockDateTime.Today; if (_todaysCodes == null || !_today.HasValue || !_today.Value.Equals(today)) { _today = today; DateTime tomorrow = today.AddDays(1); _todaysCodes = service.Queryable().AsNoTracking() .Where(c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow) .Select(c => c.Code) .ToList(); } // Find a good alphanumeric code prefix string alphaNumericCode = string.Empty; if (alphaNumericLength > 0 || alphaLength > 0) { alphaNumericCode = (alphaNumericLength > 0 ? GenerateRandomCode(alphaNumericLength) : string.Empty) + (alphaLength > 0 ? GenerateRandomAlphaCode(alphaLength) : string.Empty); while (noGood.Any(s => alphaNumericCode.Contains(s)) || _todaysCodes.Contains(alphaNumericCode)) { alphaNumericCode = (alphaNumericLength > 0 ? GenerateRandomCode(alphaNumericLength) : string.Empty) + (alphaLength > 0 ? GenerateRandomAlphaCode(alphaLength) : string.Empty); } } string numericCode = string.Empty; if (numericLength > 0) { int codeLen = alphaNumericLength + alphaLength + numericLength; var lastCode = _todaysCodes.Where(c => c.Length == codeLen).OrderBy(c => c.Substring(alphaNumericLength + alphaLength)).LastOrDefault(); numericCode = GetNextNumericCodeAsString(alphaNumericLength, alphaLength, numericLength, isRandomized, lastCode); } string code = alphaNumericCode + numericCode; _todaysCodes.Add(code); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add(attendanceCode); rockContext.SaveChanges(); return(attendanceCode); } } }
/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode"/> comprised of random alpha numeric characters. /// </summary> /// <param name="codeLength">A <see cref="System.Int32"/> representing the length of the (security) code.</param> /// <returns>A new <see cref="Rock.Model.AttendanceCode"/></returns> public static AttendanceCode GetNew(int codeLength = 3) { lock ( _obj ) { using (var rockContext = new Rock.Data.RockContext()) { var service = new AttendanceCodeService(rockContext); DateTime today = RockDateTime.Today; if (_todaysCodes == null || !_today.HasValue || !_today.Value.Equals(today)) { _today = today; DateTime tomorrow = today.AddDays(1); _todaysCodes = service.Queryable().AsNoTracking() .Where(c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow) .Select(c => c.Code) .ToList(); } // Find a good unique code for today string code = GenerateRandomCode(codeLength); while (noGood.Any(s => s == code) || _todaysCodes.Any(c => c == code)) { code = GenerateRandomCode(codeLength); } _todaysCodes.Add(code); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add(attendanceCode); rockContext.SaveChanges(); return(attendanceCode); } } }
/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode"/> /// </summary> /// <param name="codeLength">A <see cref="System.Int32"/> representing the length of the (security) code.</param> /// <returns>A new <see cref="Rock.Model.AttendanceCode"/></returns> public static AttendanceCode GetNew( int codeLength = 3 ) { lock ( _obj ) { using ( var rockContext = new Rock.Data.RockContext() ) { var service = new AttendanceCodeService( rockContext ); DateTime today = RockDateTime.Today; if ( _todaysCodes == null || !_today.HasValue || !_today.Value.Equals( today ) ) { _today = today; DateTime tomorrow = today.AddDays( 1 ); _todaysCodes = service.Queryable().AsNoTracking() .Where( c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow ) .Select( c => c.Code ) .ToList(); } // Find a good unique code for today string code = GenerateRandomCode( codeLength ); while ( noGood.Any( s => s == code ) || _todaysCodes.Any( c => c == code ) ) { code = GenerateRandomCode( codeLength ); } _todaysCodes.Add( code ); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add( attendanceCode ); rockContext.SaveChanges(); return attendanceCode; } } }
/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode" /> with a specified number of alpha characters followed by /// another specified number of numeric characters. The numeric character sequence will not repeat for "today" so /// ensure that you're using a sufficient numericLength otherwise it will be unable to find a unique number. /// Also note as the issued numeric codes reaches the maximum (from the set of possible), it will take longer and /// longer to find an unused number. /// </summary> /// <param name="alphaLength">A <see cref="System.Int32"/> representing the length of the (alpha) portion of the code.</param> /// <param name="numericLength">A <see cref="System.Int32"/> representing the length of the (digit) portion of the code.</param> /// <param name="isRandomized">A <see cref="System.Boolean"/> that controls whether or not the AttendanceCodes should be generated randomly or in order (starting from the smallest).</param> /// <returns> /// A new <see cref="Rock.Model.AttendanceCode" /> /// </returns> public static AttendanceCode GetNew(int alphaLength = 2, int numericLength = 4, bool isRandomized = true) { lock ( _obj ) { using (var rockContext = new Rock.Data.RockContext()) { var service = new AttendanceCodeService(rockContext); DateTime today = RockDateTime.Today; if (_todaysCodes == null || !_today.HasValue || !_today.Value.Equals(today)) { _today = today; DateTime tomorrow = today.AddDays(1); _todaysCodes = service.Queryable().AsNoTracking() .Where(c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow) .Select(c => c.Code) .ToList(); } // Find a good alpha code string alphaCode = GenerateRandomAlphaCode(alphaLength); while (noGood.Any(s => s == alphaCode)) { alphaCode = GenerateRandomAlphaCode(alphaLength); } // Find a good unique numeric code for today string numericCode = string.Empty; if (isRandomized) { numericCode = GenerateRandomNumericCode(numericLength); while (noGood.Any(s => s == numericCode) || _todaysCodes.Any(c => c.EndsWith(numericCode))) { numericCode = GenerateRandomNumericCode(numericLength); } } else { var lastCode = _todaysCodes.OrderBy(c => c.Substring(alphaLength)).LastOrDefault(); if (lastCode != null) { var maxCode = lastCode.Substring(alphaLength); numericCode = (maxCode.AsInteger() + 1).ToString("D" + numericLength); } else { numericCode = 0.ToString("D" + numericLength); } } string code = alphaCode + numericCode; _todaysCodes.Add(code); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add(attendanceCode); rockContext.SaveChanges(); return(attendanceCode); } } }
/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode" />. The code will contain the specified number of alphanumeric characters, /// followed by the alpha characters and then the specified number of numeric characters. The character sequence will not repeat for "today". /// Also the numeric character sequence will not repeat for "today". In both cases ensure that you're using a sufficient length for each /// otherwise there will not be enough possible codes. /// Also note as the issued numeric codes reaches the maximum (from the set of possible), it will take longer and /// longer to find an unused number. So specifing a larger number of characters then needed will increase performance. /// </summary> /// <param name="alphaNumericLength">A <see cref="System.Int32"/> representing the length for a mixed alphanumberic code.</param> /// <param name="alphaLength">A <see cref="System.Int32"/> representing the length of the (alpha) portion of the code.</param> /// <param name="numericLength">A <see cref="System.Int32"/> representing the length of the (digit) portion of the code.</param> /// <param name="isRandomized">A <see cref="System.Boolean"/> that controls whether or not the AttendanceCodes should be generated randomly or in order (starting from the smallest). Only effect the numeric code.</param> /// <returns></returns> public static AttendanceCode GetNew(int alphaNumericLength, int alphaLength, int numericLength, bool isRandomized) { lock ( _obj ) { using (var rockContext = new Rock.Data.RockContext()) { var service = new AttendanceCodeService(rockContext); DateTime today = RockDateTime.Today; if (_todaysUsedCodes == null || !_todaysDate.HasValue || !_todaysDate.Value.Equals(today)) { _todaysDate = today; DateTime tomorrow = today.AddDays(1); _todaysUsedCodes = new HashSet <string>(service.Queryable().AsNoTracking().Where(c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow).Select(c => c.Code).ToList()); } string alphaNumericCode = string.Empty; string alphaCode = string.Empty; string numericCode = string.Empty; string code = string.Empty; string lastCode = string.Empty; for (int attempts = 0; attempts <= _maxAttempts; attempts++) { if (attempts == _maxAttempts) { throw new TimeoutException("Too many attempts to create a unique attendance code. There is almost certainly a check-in system 'Security Code Length' configuration problem."); } if (alphaNumericLength > 0) { alphaNumericCode = GenerateRandomCode(alphaNumericLength); } if (alphaLength > 0) { alphaCode = GenerateRandomAlphaCode(alphaLength); } if (numericLength > 0) { int codeLen = alphaNumericLength + alphaLength + numericLength; if (lastCode.IsNullOrWhiteSpace()) { lastCode = _todaysUsedCodes.Where(c => c.Length == codeLen).OrderBy(c => c.Substring(alphaNumericLength + alphaLength)).LastOrDefault(); } numericCode = GetNextNumericCodeAsString(alphaNumericLength, alphaLength, numericLength, isRandomized, lastCode); } code = alphaNumericCode + alphaCode + numericCode; // Check if code is already in use or contains bad unallowed strings. if (noGood.Any(s => code.Contains(s)) || _todaysUsedCodes.Contains(code)) { lastCode = numericCode; alphaNumericCode = string.Empty; alphaCode = string.Empty; numericCode = string.Empty; code = string.Empty; continue; } // When using a clustered environment we need to check the DB to make sure the code hasn't been assigned by another server if (Rock.Utility.Settings.RockInstanceConfig.IsClustered) { if (service.IsCodeAlreadyInUse(code)) { lastCode = numericCode; alphaNumericCode = string.Empty; alphaCode = string.Empty; numericCode = string.Empty; code = string.Empty; continue; } } // If we get to this point the code can be used break; } _todaysUsedCodes.Add(code); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add(attendanceCode); rockContext.SaveChanges(); return(attendanceCode); } } }
protected void btnSave_Click(object sender, EventArgs e) { btnDone.Visible = true; lblPeople.Visible = true; //Create List to Save Registered People var peopleList = new List<string>(); if (Session["peopleList"] != null) { peopleList = (List<string>)Session["peopleList"]; } AttendanceCodeService attendanceCodeService = new AttendanceCodeService(rockContext); AttendanceService attendanceService = new AttendanceService(rockContext); GroupMemberService groupMemberService = new GroupMemberService(rockContext); PersonAliasService personAliasService = new PersonAliasService(rockContext); Session["person"] = ppPerson.SelectedValue.ToString(); // Only create one attendance record per day for each person/schedule/group/location DateTime theTime = Convert.ToDateTime(Session["startDateTime"]); var attendance = attendanceService.Get(theTime, int.Parse(Session["location"].ToString()), int.Parse(Session["schedule"].ToString()), int.Parse(Session["group"].ToString()), int.Parse(ppPerson.SelectedValue.ToString())); var primaryAlias = personAliasService.GetPrimaryAlias(int.Parse(ppPerson.SelectedValue.ToString())); if (attendance == null) { if (primaryAlias != null) { attendance = rockContext.Attendances.Create(); attendance.LocationId = int.Parse(Session["location"].ToString()); attendance.CampusId = int.Parse(Session["campus"].ToString()); attendance.ScheduleId = int.Parse(Session["schedule"].ToString()); attendance.GroupId = int.Parse(Session["group"].ToString()); attendance.PersonAlias = primaryAlias; attendance.PersonAliasId = primaryAlias.Id; attendance.DeviceId = null; attendance.SearchTypeValueId = 1; attendanceService.Add(attendance); } } attendance.AttendanceCodeId = null; attendance.StartDateTime = Convert.ToDateTime(Session["startDateTime"]); attendance.EndDateTime = null; attendance.DidAttend = true; //KioskLocationAttendance.AddAttendance(attendance); rockContext.SaveChanges(); //Add Person to Dictionary peopleList.Add( ppPerson.PersonName ); repLinks.DataSource = peopleList; repLinks.DataBind(); Session["peopleList"] = peopleList; //Clear Person field ppPerson.PersonId = null; ppPerson.PersonName = null; //Update Current Participants List }
/// <summary> /// Gets the new. /// </summary> /// <param name="alphaNumericLength">Length of the alpha numeric.</param> /// <param name="alphaLength">Length of the alpha.</param> /// <param name="numericLength">Length of the numeric.</param> /// <param name="isRandomized">if set to <c>true</c> [is randomized].</param> /// <returns></returns> public static AttendanceCode GetNew(int alphaNumericLength, int alphaLength, int numericLength, bool isRandomized) { lock ( _obj ) { using (var rockContext = new Rock.Data.RockContext()) { var service = new AttendanceCodeService(rockContext); DateTime today = RockDateTime.Today; if (_todaysCodes == null || !_today.HasValue || !_today.Value.Equals(today)) { _today = today; DateTime tomorrow = today.AddDays(1); _todaysCodes = new HashSet <string>(service.Queryable().AsNoTracking() .Where(c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow) .Select(c => c.Code) .ToList()); } // Find a good alphanumeric code prefix string alphaNumericCode = string.Empty; int attempts = 0; if (alphaNumericLength > 0 || alphaLength > 0) { alphaNumericCode = (alphaNumericLength > 0 ? GenerateRandomCode(alphaNumericLength) : string.Empty) + (alphaLength > 0 ? GenerateRandomAlphaCode(alphaLength) : string.Empty); while (noGood.Any(s => alphaNumericCode.Contains(s)) || _todaysCodes.Contains(alphaNumericCode)) { attempts++; // We're only going to attempt this 1 million times... // Interestingly, even when this code approaches the maximum number of possible combinations // it still typically takes less than 5000 attempts. However, if the number of // attempts jumps over 10,000 there is almost certainly a problem with someone's // check-in code configuration so we're going to stop after a million attempts. if (attempts > 1000000) { throw new TimeoutException("Too many attempts to create a unique attendance code. There is almost certainly a check-in system 'Security Code Length' configuration problem."); } alphaNumericCode = (alphaNumericLength > 0 ? GenerateRandomCode(alphaNumericLength) : string.Empty) + (alphaLength > 0 ? GenerateRandomAlphaCode(alphaLength) : string.Empty); } } string numericCode = string.Empty; if (numericLength > 0) { int codeLen = alphaNumericLength + alphaLength + numericLength; var lastCode = _todaysCodes.Where(c => c.Length == codeLen).OrderBy(c => c.Substring(alphaNumericLength + alphaLength)).LastOrDefault(); numericCode = GetNextNumericCodeAsString(alphaNumericLength, alphaLength, numericLength, isRandomized, lastCode); } string code = alphaNumericCode + numericCode; _todaysCodes.Add(code); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add(attendanceCode); rockContext.SaveChanges(); return(attendanceCode); } } }
/// <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 = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode; int securityCodeLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeLength : 3; 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( securityCodeLength ); 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 ) ) { // 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; attendance.LoadAttributes(); attendance.SetAttributeValue( "SearchValue", checkInState.CheckIn.SearchValue ); attendance.SetAttributeValue( "SearchResultGroupId", family.Group.Id ); attendanceService.Add( attendance ); } } attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; rockContext.SaveChanges(); attendance.SaveAttributeValues( rockContext ); KioskLocationAttendance.AddAttendance( attendance ); } } } } } } rockContext.SaveChanges(); return true; } return false; }
/// <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; bool reuseCodeForFamily = false; if ( bool.TryParse( GetAttributeValue( action, "ReuseCodeForFamily" ), out reuseCodeForFamily ) && reuseCodeForFamily ) { reuseCodeForFamily = true; } DateTime startDateTime = RockDateTime.Now; 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.LocationId = location.Location.Id; attendance.CampusId = location.CampuId; 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 ); } } attendance.AttendanceCodeId = attendanceCode.Id; attendance.StartDateTime = startDateTime; attendance.EndDateTime = null; attendance.DidAttend = true; KioskLocationAttendance.AddAttendance( attendance ); } } } } } } rockContext.SaveChanges(); return true; } return false; }
/// <summary> /// Returns a new <see cref="Rock.Model.AttendanceCode" /> with a specified number of alpha characters followed by /// another specified number of numeric characters. The numeric character sequence will not repeat for "today" so /// ensure that you're using a sufficient numericLength otherwise it will be unable to find a unique number. /// Also note as the issued numeric codes reaches the maximum (from the set of possible), it will take longer and /// longer to find an unused number. /// </summary> /// <param name="alphaLength">A <see cref="System.Int32"/> representing the length of the (alpha) portion of the code.</param> /// <param name="numericLength">A <see cref="System.Int32"/> representing the length of the (digit) portion of the code.</param> /// <param name="isRandomized">A <see cref="System.Boolean"/> that controls whether or not the AttendanceCodes should be generated randomly or in order (starting from the smallest).</param> /// <returns> /// A new <see cref="Rock.Model.AttendanceCode" /> /// </returns> public static AttendanceCode GetNew( int alphaLength = 2, int numericLength = 4, bool isRandomized = true ) { lock ( _obj ) { using ( var rockContext = new Rock.Data.RockContext() ) { var service = new AttendanceCodeService( rockContext ); DateTime today = RockDateTime.Today; if ( _todaysCodes == null || !_today.HasValue || !_today.Value.Equals( today ) ) { _today = today; DateTime tomorrow = today.AddDays( 1 ); _todaysCodes = service.Queryable().AsNoTracking() .Where( c => c.IssueDateTime >= today && c.IssueDateTime < tomorrow ) .Select( c => c.Code ) .ToList(); } // Find a good alpha code string alphaCode = GenerateRandomAlphaCode( alphaLength ); while ( noGood.Any( s => s == alphaCode ) ) { alphaCode = GenerateRandomAlphaCode( alphaLength ); } // Find a good unique numeric code for today string numericCode = string.Empty; if ( isRandomized ) { numericCode = GenerateRandomNumericCode( numericLength ); while ( noGood.Any( s => s == numericCode ) || _todaysCodes.Any( c => c.EndsWith( numericCode ) ) ) { numericCode = GenerateRandomNumericCode( numericLength ); } } else { var lastCode = _todaysCodes.OrderBy( c => c.Substring( alphaLength ) ).LastOrDefault(); if ( lastCode != null ) { var maxCode = lastCode.Substring( alphaLength ); numericCode = ( maxCode.AsInteger() + 1 ).ToString( "D" + numericLength ); } else { numericCode = 0.ToString( "D" + numericLength ); } } string code = alphaCode + numericCode; _todaysCodes.Add( code ); var attendanceCode = new AttendanceCode(); attendanceCode.IssueDateTime = RockDateTime.Now; attendanceCode.Code = code; service.Add( attendanceCode ); rockContext.SaveChanges(); return attendanceCode; } } }