Пример #1
0
        public void AlphaNumericWithNumericCodesShouldSkipBadCodes()
        {
            int attemptCombination = 0;

            try
            {
                var            codeList = new List <string>();
                AttendanceCode code     = null;
                for (int i = 0; i < 600; i++)
                {
                    attemptCombination = i;
                    code = AttendanceCodeService.GetNew(2, 0, 3, true);
                    codeList.Add(code.Code);
                }

                var  matches       = codeList.Where(c => AttendanceCodeService.noGood.Any(ng => c.Contains(ng)));
                bool hasMatchIsBad = matches.Any();

                Assert.IsFalse(hasMatchIsBad, "bad codes were: " + string.Join(", ", matches));
            }
            catch (TimeoutException)
            {
                // If an infinite loop was detected, but we tried at least 600 codes then
                // we'll consider this a pass.
                Assert.IsTrue(attemptCombination >= 600);
            }
        }
Пример #2
0
        public void NumericCodeWithLengthOf2ShouldNotGoBeyond99()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            try
            {
                var            codeList = new List <string>();
                AttendanceCode code     = null;
                for (int i = 0; i < 101; i++)
                {
                    code = AttendanceCodeService.GetNew(0, 0, 2, false);
                    codeList.Add(code.Code);
                }

                // should not be longer than 2 characters
                // This is a known bug in v7.4 and earlier, and possibly fixed via PR #3071
                Assert.That.IsTrue(codeList.Last().Length == 2, "last code was " + codeList.Last().Length + " characters long.");
            }
            catch (TimeoutException)
            {
                // An exception in this case is considered better than hanging (since there is
                // no actual solution).
                Assert.That.IsTrue(true);
            }
            finally
            {
                stopWatch.Stop();
                System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
                System.Diagnostics.Trace.WriteLine(string.Format("Test NumericCodeWithLengthOf2ShouldNotGoBeyond99 took {0} ms.", stopWatch.ElapsedMilliseconds));
            }
        }
Пример #3
0
        public void RequestingMoreCodesThanPossibleShouldThrowException()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            // Generate 99 codes (the maximum number of valid codes).
            for (int i = 0; i < 100; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 2, true);
                codeList.Add(code.Code);
            }

            // Now try to generate one more... which should NOT hang but instead, may
            // throw one of two exceptions.
            try
            {
                code = AttendanceCodeService.GetNew(0, 0, 2, true);
            }
            catch (InvalidOperationException)
            {
                Assert.IsTrue(true);
            }
            catch (TimeoutException)
            {
                // An exception in this case is considered better than hanging (since there is
                // no actual solution).
                Assert.IsTrue(true);
            }
        }
Пример #4
0
        public void AlphaOnlyCodesShouldNotRepeat()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            // 4847 (17*17*17 minus ~50 bad codes) possible combinations of 17 letters
            for (int i = 0; i < 4860; i++)
            {
                //System.Diagnostics.Debug.WriteIf( i > 4700, "code number " + i + " took... " );
                code = AttendanceCodeService.GetNew(0, 3, 0, false);
                codeList.Add(code.Code);
                //System.Diagnostics.Debug.WriteLineIf( i > 4700, "" );
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.That.IsTrue(duplicates.Count() == 0);

            stopWatch.Stop();
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.WriteLine(string.Format("Test AlphaOnlyCodesShouldNotRepeat took {0} ms.", stopWatch.ElapsedMilliseconds));
        }
Пример #5
0
        public void RandomNumericCodesShouldNotRepeat()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 998; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, true);
                codeList.Add(code.Code);
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.That.IsTrue(duplicates.Count() == 0, "repeated codes: " + string.Join(", ", duplicates));

            stopWatch.Stop();
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.WriteLine(string.Format("Test RandomNumericCodesShouldNotRepeat took {0} ms.", stopWatch.ElapsedMilliseconds));
        }
Пример #6
0
        public void TwoAlphaWithFourRandomNumericCodesShouldSkipBadCodes()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            int attemptCombination = 0;

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 2500; i++)
            {
                attemptCombination = i;
                code = AttendanceCodeService.GetNew(0, 2, 4, true);
                codeList.Add(code.Code);
            }

            // TODO: Once the combination of codes issue is addressed, this next line should be uncommented
            // and replace the one below it:
            //var matches = codeList.Where( c => AttendanceCodeService.noGood.Any( ng => c.Contains( ng ) ) );
            var matches = codeList.Select(x => x).Intersect(AttendanceCodeService.noGood);

            bool hasMatchIsBad = matches.Any();

            Assert.That.IsFalse(hasMatchIsBad, "bad codes were: " + string.Join(", ", matches));

            stopWatch.Stop();
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.WriteLine(string.Format("Test AlphaOnlyWithNumericOnlyCodesShouldSkipBadCodes took {0} ms.", stopWatch.ElapsedMilliseconds));
        }
Пример #7
0
        public void NumericCodeWithLengthOf2ShouldNotGoBeyond99()
        {
            Cleanup();

            try
            {
                var            codeList = new List <string>();
                AttendanceCode code     = null;
                for (int i = 0; i < 101; i++)
                {
                    code = AttendanceCodeService.GetNew(0, 0, 2, false);
                    codeList.Add(code.Code);
                }

                // should not be longer than 4 characters
                // This is a known bug in v7.4 and earlier, and possibly fixed via PR #3071
                Assert.True(codeList.Last().Length == 4);
            }
            catch (TimeoutException)
            {
                // An exception in this case is considered better than hanging (since there is
                // no actual solution).
                Assert.True(true);
            }
        }
Пример #8
0
        public void AlphaNumericWithNumericCodesShouldSkipBadCodes()
        {
            Cleanup();
            int attemptCombination = 0;

            try
            {
                var            codeList = new List <string>();
                AttendanceCode code     = null;
                for (int i = 0; i < 676; i++)
                {
                    attemptCombination = i;
                    code = AttendanceCodeService.GetNew(2, 0, 2, true);
                    codeList.Add(code.Code);
                }

                bool hasMatchIsBad = codeList.Where(c => noGood.Any(ng => c.Contains(ng))).Any();

                Assert.False(hasMatchIsBad);
            }
            catch (TimeoutException)
            {
                // If an infinite loop was detected, but we tried at least 616 codes then
                // we'll consider this a pass.
                Assert.True(attemptCombination >= 616);
            }
        }
Пример #9
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;
        }
Пример #10
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 AttendanceCode GetNew(int codeLength = 3)
        {
            string code = string.Empty;

            var attendanceCode = new AttendanceCode();

            // 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 ) ||
                    Get(DateTime.Today, code).Any())
                {
                    code = GenerateRandomCode( codeLength );
                }

                attendanceCode.IssueDateTime = DateTime.Now;
                attendanceCode.Code = code;
                this.Add( attendanceCode, null );
                this.Save( attendanceCode, null );
            }

            return attendanceCode;
        }
Пример #11
0
        public void AlphaNumericWith1NumericCodeShouldGenerateAtLeast5100Codes()
        {
            int attemptCombination = 0;
            var stopWatch          = new System.Diagnostics.Stopwatch();
            var stopWatchSingle    = new System.Diagnostics.Stopwatch();

            stopWatch.Start();
            stopWatchSingle.Start();
            var outputDebug = false;

            try
            {
                var            codeList = new List <string>();
                AttendanceCode code     = null;
                for (int i = 1; i < 5100; i++)
                {
                    attemptCombination = i;
                    if (i > 4000 && i % 100 == 0)
                    {
                        outputDebug = true;
                        stopWatchSingle.Restart();
                        System.Diagnostics.Debug.Write("code number " + i + " took... ");
                    }
                    code = AttendanceCodeService.GetNew(2, 0, 1, true);
                    if (outputDebug)
                    {
                        System.Diagnostics.Debug.WriteLine(stopWatchSingle.ElapsedMilliseconds + " ms");
                        outputDebug = false;
                    }
                    codeList.Add(code.Code);
                }

                var  matches       = codeList.Where(c => AttendanceCodeService.NoGood.Any(ng => c.Contains(ng)));
                bool hasMatchIsBad = matches.Any();

                Assert.That.IsFalse(hasMatchIsBad, "bad codes were: " + string.Join(", ", matches));

                var duplicates = codeList.GroupBy(x => x)
                                 .Where(group => group.Count() > 1)
                                 .Select(group => group.Key);

                Assert.That.True(duplicates.Count() == 0);
            }
            catch (TimeoutException)
            {
                // If an infinite loop was detected, but we tried at least 5100 codes then
                // we'll consider this a pass.
                Assert.That.IsTrue(attemptCombination >= 5100);
            }
            finally
            {
                stopWatch.Stop();
                System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
                System.Diagnostics.Trace.WriteLine(string.Format("Test AlphaNumericWith1NumericCodeShouldGenerateAtLeast5100Codes took {0} ms.", stopWatch.ElapsedMilliseconds));
            }
        }
Пример #12
0
        public void Increment100SequentialNumericCodes()
        {
            AttendanceCode code = null;

            for (int i = 0; i < 100; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
            }

            Assert.That.Equal("100", code.Code);
        }
Пример #13
0
        public void CheckThreeCharNumericNonRandom002Code()
        {
            AttendanceCode code = null;

            for (int i = 0; i < 2; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
            }

            Assert.That.Equal("002", code.Code);
        }
Пример #14
0
        public void CheckThreeChar002Code()
        {
            AttendanceCode code = null;

            for (int i = 0; i < 2; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
            }

            Assert.AreEqual("002", code.Code);
        }
Пример #15
0
        private void LoadFromModel(AttendanceCode model)
        {
            Code        = model.Code;
            Description = model.Description;
            MeaningId   = model.MeaningId;
            Active      = model.Active;
            Restricted  = model.Restricted;

            if (model.CodeType != null)
            {
                CodeType = new AttendanceCodeTypeModel(model.CodeType);
            }
        }
Пример #16
0
        public void NumericCodesShouldSkip911And666()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 2000; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 4, false);
                codeList.Add(code.Code);
            }

            Assert.That.DoesNotContain(codeList, "911");
            Assert.That.DoesNotContain(codeList, "666");
        }
Пример #17
0
        public void NumericCodesShouldNotContain911And666()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 2000; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 4, false);
                codeList.Add(code.Code);
            }

            Assert.IsFalse(codeList.Any(s => s.Contains("911")));
            Assert.IsFalse(codeList.Any(s => s.Contains("666")));
        }
Пример #18
0
        public void ThreeCharAlphaWithFourCharNumericCodesShouldSkipBadCodes()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 6000; i++)
            {
                code = AttendanceCodeService.GetNew(0, 3, 4, true);
                codeList.Add(code.Code);
            }

            bool hasMatchIsBad = codeList.Where(c => AttendanceCodeService.NoGood.Any(ng => c.Contains(ng))).Any();

            Assert.That.False(hasMatchIsBad);
        }
Пример #19
0
        public void AlphaOnlyCodesShouldSkipBadCodes()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 1000; i++)
            {
                code = AttendanceCodeService.GetNew(0, 3, 0, true);
                codeList.Add(code.Code);
            }

            bool hasMatchIsBad = codeList.Where(c => AttendanceCodeService.noGood.Any(ng => c.Contains(ng))).Any();

            Assert.That.IsFalse(hasMatchIsBad);
        }
Пример #20
0
        public void AlphaOnlyWithNumericOnlyCodesShouldSkipBadCodes()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 6000; i++)
            {
                code = AttendanceCodeService.GetNew(0, 1, 4, true);
                codeList.Add(code.Code);
            }

            var  matches       = codeList.Where(c => AttendanceCodeService.noGood.Any(ng => c.Contains(ng)));
            bool hasMatchIsBad = matches.Any();

            Assert.IsFalse(hasMatchIsBad, "bad codes were: " + string.Join(", ", matches));
        }
Пример #21
0
        public void AlphaNumericCodesShouldNeverContain911And666()
        {
            Cleanup();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 10000; i++)
            {
                code = AttendanceCodeService.GetNew(3, 0, 2, false);
                codeList.Add(code.Code);
            }

            Assert.False(codeList.Any(s => "911".Contains(s)));
            Assert.False(codeList.Any(s => "666".Contains(s)));
        }
Пример #22
0
        public void RandomNumericCodesShouldNotRepeat()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 998; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, true);
                codeList.Add(code.Code);
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.IsTrue(duplicates.Count() == 0, "repeated codes: " + string.Join(", ", duplicates));
        }
Пример #23
0
        public void AlphaNumericCodesShouldSkipBadCodes()
        {
            Cleanup();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 6000; i++)
            {
                code = AttendanceCodeService.GetNew(3, 0, 0, false);
                codeList.Add(code.Code);
            }

            bool hasMatchIsBad = codeList.Where(c => noGood.Any(ng => c.Contains(ng))).Any();

            Assert.False(hasMatchIsBad);
        }
Пример #24
0
        public void NumericCodeWithLengthOf2ShouldNotGoBeyond99()
        {
            Cleanup();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 101; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 2, false);
                codeList.Add(code.Code);
            }

            // should not be longer than 4 characters
            // This is a known bug in v7.4 and earlier, and possibly fixed via PR #3071
            Assert.True(codeList.Last().Length == 4);
        }
Пример #25
0
        public void RandomNumericCodesShouldNotRepeat()
        {
            int            maxThreeDigitCodes = 997;
            var            codeList           = new List <string>();
            AttendanceCode code = null;

            for (int i = 1; i < maxThreeDigitCodes; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, true);
                codeList.Add(code.Code);
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.That.True(duplicates.Count() == 0);
        }
Пример #26
0
        public void Increment100SequentialNumericCodes()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            AttendanceCode code = null;

            for (int i = 0; i < 100; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
            }

            Assert.That.AreEqual("100", code.Code);

            stopWatch.Stop();
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.WriteLine(string.Format("Test Increment100SequentialNumericCodes took {0} ms.", stopWatch.ElapsedMilliseconds));
        }
Пример #27
0
        public void AlphaNumericCodesShouldSkipBadCodes()
        {
            Cleanup();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 6000; i++)
            {
                code = AttendanceCodeService.GetNew(3, 0, 0, false);
                codeList.Add(code.Code);
            }

            bool hasMatchIsBad = codeList.Select(x => x)
                                 .Intersect(noGood)
                                 .Any();

            Assert.False(hasMatchIsBad);
        }
Пример #28
0
        public void CheckThreeChar002Code()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            AttendanceCode code = null;

            for (int i = 0; i < 2; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
            }

            Assert.That.AreEqual("002", code.Code);

            stopWatch.Stop();
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.WriteLine(string.Format("Test CheckThreeChar002Code took {0} ms.", stopWatch.ElapsedMilliseconds));
        }
Пример #29
0
        public void NumericCodesShouldNotRepeat()
        {
            Cleanup();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            for (int i = 0; i < 999; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 3, false);
                codeList.Add(code.Code);
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.True(duplicates.Count() == 0);
        }
Пример #30
0
        public void ThreeCharAlphaOnlyCodesShouldNotRepeat()
        {
            var            codeList = new List <string>();
            AttendanceCode code     = null;

            // 4800 (17*17*17 minus ~80 badcodes) possible combinations of 17 letters
            for (int i = 0; i < 4800; i++)
            {
                //System.Diagnostics.Debug.WriteIf( i > 4700, "code number " + i + " took... " );
                code = AttendanceCodeService.GetNew(0, 3, 0, false);
                codeList.Add(code.Code);
                //System.Diagnostics.Debug.WriteLineIf( i > 4700, "" );
            }

            var duplicates = codeList.GroupBy(x => x)
                             .Where(group => group.Count() > 1)
                             .Select(group => group.Key);

            Assert.That.True(duplicates.Count() == 0);
        }
Пример #31
0
        public int CreateAttendanceCode(AttendanceCode attendanceCode)
        {
            try
            {
                SqlParameter[] m = new SqlParameter[5];
                m[0] = new SqlParameter("@ID", SqlDbType.Int);
                m[1] = new SqlParameter("@GroupID", attendanceCode.GroupID);
                m[2] = new SqlParameter("@AttendanceDate", attendanceCode.AttendanceDate);
                m[3] = new SqlParameter("@AttendanceCode", attendanceCode.Code);
                m[4] = new SqlParameter("@CreateDate", attendanceCode.CreateDate);

                m[0].Direction = ParameterDirection.Output;
                SqlHelper.ExecuteNonQuery(Connection.Connection_string, CommandType.StoredProcedure, "AttendanceCodeInsert", m);
                object ivalue = m[0].Value;
                return((int)ivalue);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Пример #32
0
        public void RequestingMoreCodesThanPossibleShouldThrowException()
        {
            var stopWatch = new System.Diagnostics.Stopwatch();

            stopWatch.Start();

            var            codeList = new List <string>();
            AttendanceCode code     = null;

            // Generate 99 codes (the maximum number of valid codes).
            for (int i = 0; i < 100; i++)
            {
                code = AttendanceCodeService.GetNew(0, 0, 2, true);
                codeList.Add(code.Code);
            }

            // Now try to generate one more... which should NOT hang but instead, may
            // throw one of two exceptions.
            try
            {
                code = AttendanceCodeService.GetNew(0, 0, 2, true);
            }
            catch (InvalidOperationException)
            {
                Assert.That.IsTrue(true);
            }
            catch (TimeoutException)
            {
                // An exception in this case is considered better than hanging (since there is
                // no actual solution).
                Assert.That.IsTrue(true);
            }
            finally
            {
                stopWatch.Stop();
                System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
                System.Diagnostics.Trace.WriteLine(string.Format("Test RequestingMoreCodesThanPossibleShouldThrowException took {0} ms.", stopWatch.ElapsedMilliseconds));
            }
        }
        /// <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;
                }
            }
        }
Пример #35
0
        /// <summary>
        /// Adds attendance data for each child for each weekend since the starting date up to
        /// the weekend ending X weeks ago (endingWeeksAgo).  It will randomly skip a weekend
        /// based on the percentage (pctAttendance) and it will vary which service they attend
        /// between the scheduleId and altScheduleId based on the percentage (pctAttendedRegularService)
        /// given.
        /// </summary>
        /// <param name="familyMembers">The family members.</param>
        /// <param name="startingDate">The first date of attendance</param>
        /// <param name="endDate">The end date of attendance</param>
        /// <param name="pctAttendance">The PCT attendance.</param>
        /// <param name="pctAttendedRegularService">The PCT attended regular service.</param>
        /// <param name="scheduleId">The schedule identifier.</param>
        /// <param name="altScheduleId">The alt schedule identifier.</param>
        /// <param name="attendanceData">The attendance data.</param>
        private void CreateAttendance( ICollection<GroupMember> familyMembers, DateTime startingDate, DateTime endDate, 
            int pctAttendance, int pctAttendedRegularService, int scheduleId, int altScheduleId, Dictionary<Guid, List<Attendance>> attendanceData )
        {
            // foreach weekend between the starting and ending date...
            for ( DateTime date = startingDate; date <= endDate; date = date.AddDays( 7 ) )
            {
                // set an additional factor
                int summerFactor = ( 7 <= date.Month && date.Month <= 9 ) ? summerPercentFactor : 0;
                if ( _random.Next( 0, 100 ) > pctAttendance - summerFactor )
                {
                    continue; // skip this week
                }

                // which service did they attend
                int serviceSchedId = ( _random.Next( 0, 100 ) > pctAttendedRegularService ) ? scheduleId : altScheduleId;

                // randomize check-in time slightly by +- 0-15 minutes (and 1 out of 4 times being late)
                int minutes = _random.Next( 0, 15 );
                int plusMinus = ( _random.Next( 0, 4 ) == 0 ) ? 1 : -1;
                int randomSeconds = _random.Next( 0, 60 );

                var time = _scheduleTimes[serviceSchedId];

                DateTime dtTime = new DateTime( date.Year, date.Month, date.Day, time.Hour, time.Minute, time.Second );
                DateTime checkinDateTime = dtTime.AddMinutes( Convert.ToDouble( plusMinus * minutes ) ).AddSeconds( randomSeconds );

                // foreach child in the family
                foreach ( var member in familyMembers.Where( m => m.GroupRoleId == _childRoleId ) )
                {
                    // Find a class room (group location)
                    // TODO -- someday perhaps we will change this to actually find a real GroupLocationSchedule record
                    var item = ( from classroom in _classes
                                 where member.Person.AgePrecise >= classroom.MinAge
                                 && member.Person.AgePrecise <= classroom.MaxAge
                                 orderby classroom.MinAge, classroom.MaxAge
                                 select classroom ).FirstOrDefault();

                    // If no suitable classroom was found, skip
                    if ( item == null )
                    {
                        continue;
                    }

                    // Only create one attendance record per day for each person/schedule/group/location
                    AttendanceCode attendanceCode = new AttendanceCode()
                    {
                        Code = GenerateRandomCode( _securityCodeLength ),
                        IssueDateTime = RockDateTime.Now,
                    };

                    Attendance attendance = new Attendance()
                    {
                        ScheduleId = scheduleId,
                        GroupId = item.GroupId,
                        LocationId = item.LocationId,
                        DeviceId = _kioskDeviceId,
                        AttendanceCode = attendanceCode,
                        StartDateTime = checkinDateTime,
                        EndDateTime = null,
                        DidAttend = true,
                        CampusId = 1
                    };

                    if ( !attendanceData.Keys.Contains( member.Person.Guid ))
                    {
                        attendanceData.Add( member.Person.Guid, new List<Attendance>());
                    }
                    attendanceData[member.Person.Guid].Add( attendance);
                }
            }
        }