Data Access/Service class for Rock.Model.AttendanceCode entity types
예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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);
                }
            }
        }
예제 #3
0
        /// <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;
                }
            }
        }
예제 #5
0
        /// <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);
                }
            }
        }
예제 #7
0
        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;
        }
예제 #10
0
        /// <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;
        }
예제 #11
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 )
            {
                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;
                }
            }
        }