示例#1
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             = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
                int  securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3;
                int  securityCodeAlphaLength        = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0;
                int  securityCodeNumericLength      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0;
                bool securityCodeNumericRandom      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true;


                var attendanceCodeService = new AttendanceCodeService(rockContext);
                var attendanceService     = new AttendanceService(rockContext);
                var groupMemberService    = new GroupMemberService(rockContext);
                var personAliasService    = new PersonAliasService(rockContext);


                var family = checkInState.CheckIn.CurrentFamily;
                if (family != null)
                {
                    foreach (var person in family.GetPeople(true))
                    {
                        if (reuseCodeForFamily && attendanceCode != null)
                        {
                            person.SecurityCode = attendanceCode.Code;
                        }
                        else
                        {
                            attendanceCode      = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom);
                            person.SecurityCode = attendanceCode.Code;
                        }

                        foreach (var groupType in person.GetGroupTypes(true))
                        {
                            foreach (var group in groupType.GetGroups(true))
                            {
                                if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn &&
                                    groupType.GroupType.DefaultGroupRoleId.HasValue &&
                                    !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any())
                                {
                                    var groupMember = new GroupMember();
                                    groupMember.GroupId     = group.Group.Id;
                                    groupMember.PersonId    = person.Person.Id;
                                    groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value;
                                    groupMemberService.Add(groupMember);
                                }

                                foreach (var location in group.GetLocations(true))
                                {
                                    foreach (var schedule in location.GetSchedules(true))
                                    {
                                        var startDateTime = schedule.CampusCurrentDateTime;

                                        // Only create one attendance record per day for each person/schedule/group/location
                                        var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id);
                                        if (attendance == null)
                                        {
                                            var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                            if (primaryAlias != null)
                                            {
                                                attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, group.Group.Id,
                                                                                           location.Location.Id, schedule.Schedule.Id, location.CampusId,
                                                                                           checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id,
                                                                                           checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id);

                                                attendance.PersonAlias = primaryAlias;
                                            }
                                        }

                                        attendance.DeviceId                 = checkInState.Kiosk.Device.Id;
                                        attendance.SearchTypeValueId        = checkInState.CheckIn.SearchType.Id;
                                        attendance.SearchValue              = checkInState.CheckIn.SearchValue;
                                        attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId;
                                        attendance.SearchResultGroupId      = family.Group.Id;
                                        attendance.AttendanceCodeId         = attendanceCode.Id;
                                        attendance.StartDateTime            = startDateTime;
                                        attendance.EndDateTime              = null;
                                        attendance.DidAttend                = true;
                                        attendance.Note = group.Notes;

                                        KioskLocationAttendance.AddAttendance(attendance);
                                    }
                                }
                            }
                        }
                    }
                }

                rockContext.SaveChanges();
                return(true);
            }

            return(false);
        }
示例#2
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>
        public override bool Execute(RockContext rockContext, Model.WorkflowAction action, object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState == null)
            {
                return(false);
            }

            AttendanceCode attendanceCode = null;

            bool reuseCodeForFamily             = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
            int  securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3;
            int  securityCodeAlphaLength        = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0;
            int  securityCodeNumericLength      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0;
            bool securityCodeNumericRandom      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true;

            bool enablePresence = checkInState.CheckInType != null && checkInState.CheckInType.EnablePresence;

            var attendanceCodeService = new AttendanceCodeService(rockContext);
            var attendanceService     = new AttendanceService(rockContext);
            var groupMemberService    = new GroupMemberService(rockContext);
            var personAliasService    = new PersonAliasService(rockContext);
            var attendanceRecords     = new List <Attendance>();

            AttendanceCheckInSession attendanceCheckInSession = new AttendanceCheckInSession()
            {
                DeviceId        = checkInState.DeviceId,
                ClientIpAddress = RockPage.GetClientIpAddress()
            };

            checkInState.Messages.Clear();

            var family = checkInState.CheckIn.CurrentFamily;

            if (family != null)
            {
                var currentOccurrences = new List <OccurrenceRecord>();
                foreach (var person in family.GetPeople(true))
                {
                    if (reuseCodeForFamily && attendanceCode != null)
                    {
                        person.SecurityCode = attendanceCode.Code;
                    }
                    else
                    {
                        attendanceCode      = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom);
                        person.SecurityCode = attendanceCode.Code;
                    }

                    foreach (var groupType in person.GetGroupTypes(true))
                    {
                        foreach (var group in groupType.GetGroups(true))
                        {
                            if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn &&
                                groupType.GroupType.DefaultGroupRoleId.HasValue &&
                                !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any())
                            {
                                var groupMember = new GroupMember();
                                groupMember.GroupId     = group.Group.Id;
                                groupMember.PersonId    = person.Person.Id;
                                groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value;
                                groupMemberService.Add(groupMember);
                            }

                            foreach (var location in group.GetLocations(true))
                            {
                                bool isCheckedIntoLocation = false;
                                foreach (var schedule in location.GetSchedules(true))
                                {
                                    var startDateTime = schedule.CampusCurrentDateTime;

                                    // If we're enforcing strict location thresholds, then before we create an attendance record
                                    // we need to check the location-schedule's current count.
                                    if (GetAttributeValue(action, AttributeKey.EnforceStrictLocationThreshold).AsBoolean() && location.Location.SoftRoomThreshold.HasValue)
                                    {
                                        EnforceStrictLocationThreshold(action, checkInState, attendanceService, currentOccurrences, person, group, location, schedule, startDateTime);
                                    }

                                    // Only create one attendance record per day for each person/schedule/group/location
                                    var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id);
                                    if (attendance == null)
                                    {
                                        var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                        if (primaryAlias != null)
                                        {
                                            attendance = attendanceService.AddOrUpdate(
                                                primaryAlias.Id,
                                                startDateTime.Date,
                                                group.Group.Id,
                                                location.Location.Id,
                                                schedule.Schedule.Id,
                                                location.CampusId,
                                                checkInState.Kiosk.Device.Id,
                                                checkInState.CheckIn.SearchType?.Id,
                                                checkInState.CheckIn.SearchValue,
                                                family.Group.Id,
                                                attendanceCode.Id);

                                            attendance.PersonAlias = primaryAlias;
                                        }
                                    }

                                    attendance.AttendanceCheckInSession = attendanceCheckInSession;

                                    attendance.DeviceId                  = checkInState.Kiosk.Device.Id;
                                    attendance.SearchTypeValueId         = checkInState.CheckIn.SearchType?.Id;
                                    attendance.SearchValue               = checkInState.CheckIn.SearchValue;
                                    attendance.CheckedInByPersonAliasId  = checkInState.CheckIn.CheckedInByPersonAliasId;
                                    attendance.SearchResultGroupId       = family.Group.Id;
                                    attendance.AttendanceCodeId          = attendanceCode.Id;
                                    attendance.StartDateTime             = startDateTime;
                                    attendance.EndDateTime               = null;
                                    attendance.CheckedOutByPersonAliasId = null;
                                    attendance.DidAttend                 = true;
                                    attendance.Note        = group.Notes;
                                    attendance.IsFirstTime = person.FirstTime;

                                    /*
                                     *  7/16/2020 - JH
                                     *  If EnablePresence is true for this Check-in configuration, it will be the responsibility of the room
                                     *  attendants to mark a given Person as present, so do not set the 'Present..' property values below.
                                     *  Otherwise, set the values to match those of the Check-in values: the Person checking them in will
                                     *  have simultaneously marked them as present.
                                     *
                                     *  Also, note that we sometimes reuse Attendance records (i.e. the Person was already checked into this
                                     *  schedule/group/location, might have already been checked out, and also might have been previously
                                     *  marked as present). In this case, the same 'Present..' rules apply, but we might need to go so far
                                     *  as to null-out the previously set 'Present..' property values, hence the conditional operators below.
                                     */
                                    attendance.PresentDateTime        = enablePresence ? ( DateTime? )null : startDateTime;
                                    attendance.PresentByPersonAliasId = enablePresence ? null : checkInState.CheckIn.CheckedInByPersonAliasId;

                                    KioskLocationAttendance.AddAttendance(attendance);
                                    isCheckedIntoLocation = true;

                                    // Keep track of attendance (Ids) for use by other actions later in the workflow pipeline
                                    attendanceRecords.Add(attendance);
                                }

                                // If the person was NOT checked into the location for any schedule then remove the location
                                if (!isCheckedIntoLocation)
                                {
                                    group.Locations.Remove(location);
                                }
                            }
                        }
                    }
                }
            }

            if (checkInState.CheckInType.AchievementTypes.Any())
            {
                // Get any achievements that were in-progress *prior* to adding these attendance records
                var configuredAchievementTypeIds    = checkInState.CheckInType.AchievementTypes.Select(a => a.Id).ToList();
                var attendanceRecordsPersonAliasIds = attendanceRecords.Where(a => a.PersonAliasId.HasValue).Select(a => a.PersonAliasId.Value).ToArray();
                var successfullyCompletedAchievementsPriorToSaveChanges = GetSuccessfullyCompletedAchievementAttempts(rockContext, attendanceRecordsPersonAliasIds, configuredAchievementTypeIds);

                rockContext.SaveChanges();

                AchievementAttemptService.AchievementAttemptWithPersonAlias[] achievementAttemptsAfterSaveChanges =
                    GetAchievementAttemptsWithPersonAliasQuery(rockContext, attendanceRecordsPersonAliasIds, configuredAchievementTypeIds).AsNoTracking().ToArray();

                checkInState.CheckIn.SuccessfullyCompletedAchievementsPriorToCheckin = successfullyCompletedAchievementsPriorToSaveChanges;
                checkInState.CheckIn.AchievementsStateAfterCheckin = achievementAttemptsAfterSaveChanges;
            }
            else
            {
                rockContext.SaveChanges();
            }

            // Now that the records are persisted, take the Ids and save them to the temp CheckInFamliy object
            family.AttendanceIds = attendanceRecords.Select(a => a.Id).ToList();
            family.AttendanceCheckinSessionGuid = attendanceCheckInSession.Guid;
            attendanceRecords = null;

            return(true);
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The workflow action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override bool Execute(RockContext rockContext, Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null)
            {
                Guid checkinGroupAttributeGuid = GetAttributeValue(action, "CheckinGroupAttribute").AsGuid();
                if (checkinGroupAttributeGuid == Guid.Empty)
                {
                    throw new Exception("CheckInGroupAttribute not set. Set attribute to continue.");
                }
                string checkinGroupAttributeKey = AttributeCache.Read(checkinGroupAttributeGuid, rockContext).Key;

                string sessionAttributeKey = GetAttributeValue(action, "SessionAttributeKey");

                AttendanceCode attendanceCode = null;
                DateTime       startDateTime  = RockDateTime.Now;

                bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
                int  securityCodeLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3;

                AttendanceCodeService attendanceCodeService = new AttendanceCodeService(rockContext);
                AttendanceService     attendanceService     = new AttendanceService(rockContext);
                GroupMemberService    groupMemberService    = new GroupMemberService(rockContext);
                PersonAliasService    personAliasService    = new PersonAliasService(rockContext);
                GroupService          groupService          = new GroupService(rockContext);

                var family = checkInState.CheckIn.CurrentFamily;
                if (family != null)
                {
                    foreach (var person in family.GetPeople(true))
                    {
                        if (reuseCodeForFamily && attendanceCode != null)
                        {
                            person.SecurityCode = attendanceCode.Code;
                        }
                        else
                        {
                            attendanceCode      = AttendanceCodeService.GetNew(securityCodeLength);
                            person.SecurityCode = attendanceCode.Code;
                        }

                        foreach (var groupType in person.GetGroupTypes(true))
                        {
                            foreach (var group in groupType.GetGroups(true))
                            {
                                var referenceGroupGuid = group.Group.GetAttributeValue(checkinGroupAttributeKey).AsGuid();
                                var referenceGroup     = groupService.Get(referenceGroupGuid);
                                if (referenceGroup == null)
                                {
                                    group.Selected = false;
                                    continue;
                                }
                                GroupMember groupMember = groupMemberService.GetByGroupIdAndPersonId(referenceGroup.Id, person.Person.Id).FirstOrDefault();
                                if (groupMember == null)
                                {
                                    group.Selected = false;
                                    continue;
                                }
                                groupMember.LoadAttributes();
                                int sessions = groupMember.GetAttributeValue(sessionAttributeKey).AsInteger();

                                foreach (var location in group.GetLocations(true))
                                {
                                    foreach (var schedule in location.GetSchedules(true))
                                    {
                                        if (sessions == 0)
                                        {
                                            continue;
                                        }

                                        // Only create one attendance record per day for each person/schedule/group/location
                                        var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id);
                                        if (attendance == null)
                                        {
                                            var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                            if (primaryAlias != null)
                                            {
                                                attendance                   = rockContext.Attendances.Create();
                                                attendance.LocationId        = location.Location.Id;
                                                attendance.CampusId          = location.CampusId;
                                                attendance.ScheduleId        = schedule.Schedule.Id;
                                                attendance.GroupId           = group.Group.Id;
                                                attendance.PersonAlias       = primaryAlias;
                                                attendance.PersonAliasId     = primaryAlias.Id;
                                                attendance.DeviceId          = checkInState.Kiosk.Device.Id;
                                                attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id;
                                                attendanceService.Add(attendance);
                                            }

                                            //decrement sessions and save
                                            sessions--;
                                            groupMember.SetAttributeValue(sessionAttributeKey, sessions);
                                            groupMember.SaveAttributeValues();
                                        }
                                        else
                                        {
                                            foreach (var cPerson in checkInState.CheckIn.Families.SelectMany(f => f.People))
                                            {
                                                cPerson.Selected = false;
                                                cPerson.GroupTypes.ForEach(gt => gt.Selected = false);
                                            }
                                            return(true);
                                        }

                                        attendance.AttendanceCodeId = attendanceCode.Id;
                                        attendance.StartDateTime    = startDateTime;
                                        attendance.EndDateTime      = null;
                                        attendance.DidAttend        = true;

                                        KioskLocationAttendance.AddAttendance(attendance);
                                    }
                                }
                            }
                        }
                    }
                }

                rockContext.SaveChanges();
                return(true);
            }
            return(false);
        }
示例#4
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, Rock.Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null)
            {
                AttendanceCode attendanceCode = null;
                DateTime       startDateTime  = Rock.RockDateTime.Now;
                DateTime       today          = startDateTime.Date;
                DateTime       tomorrow       = startDateTime.AddDays(1);

                bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
                int  securityCodeLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 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))
                                    {
                                        var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                        if (primaryAlias != null)
                                        {
                                            // If a like attendance service exists close it before creating another one.
                                            var oldAttendance = attendanceService.Queryable()
                                                                .Where(a =>
                                                                       a.StartDateTime >= today &&
                                                                       a.StartDateTime < tomorrow &&
                                                                       a.Occurrence.LocationId == location.Location.Id &&
                                                                       a.Occurrence.ScheduleId == schedule.Schedule.Id &&
                                                                       a.Occurrence.GroupId == group.Group.Id &&
                                                                       a.PersonAlias.PersonId == person.Person.Id)
                                                                .FirstOrDefault();

                                            if (oldAttendance != null)
                                            {
                                                oldAttendance.EndDateTime = Rock.RockDateTime.Now;
                                                oldAttendance.DidAttend   = false;
                                            }
                                            var attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, group.Group.Id,
                                                                                           location.Location.Id, schedule.Schedule.Id, location.CampusId,
                                                                                           checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id,
                                                                                           checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id);

                                            attendance.DeviceId                 = checkInState.Kiosk.Device.Id;
                                            attendance.SearchTypeValueId        = checkInState.CheckIn.SearchType.Id;
                                            attendance.SearchValue              = checkInState.CheckIn.SearchValue;
                                            attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId;
                                            attendance.SearchResultGroupId      = family.Group.Id;
                                            attendance.AttendanceCodeId         = attendanceCode.Id;
                                            attendance.StartDateTime            = startDateTime;
                                            attendance.EndDateTime              = null;
                                            attendance.Note      = group.Notes;
                                            attendance.DidAttend = groupType.GroupType.GetAttributeValue("SetDidAttend").AsBoolean();

                                            attendanceService.Add(attendance);
                                            CheckInCountCache.AddAttendance(attendance);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                rockContext.SaveChanges();
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The workflow action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override bool Execute(RockContext rockContext, Rock.Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var isMobile          = GetAttributeValue(action, "IsMobile").AsBoolean();
            var mobileDidAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_DID_ATTEND).Id;
            var mobileNotAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_NOT_ATTEND).Id;

            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null)
            {
                KioskService kioskService = new KioskService(rockContext);
                var          kioskTypeId  = kioskService.GetByClientName(checkInState.Kiosk.Device.Name).KioskTypeId;
                var          kioskType    = KioskTypeCache.Get(kioskTypeId.Value);
                var          campusId     = kioskType.CampusId;
                if (campusId == null)
                {
                    var compatableKioskType = KioskTypeCache.All().Where(kt => kt.CampusId.HasValue && kt.CheckinTemplateId == kioskType.CheckinTemplateId).FirstOrDefault();
                    if (compatableKioskType != null)
                    {
                        campusId = compatableKioskType.CampusId;
                    }
                    else
                    {
                        campusId = 0;
                    }
                }

                campusId = GetCampusOrFamilyCampusId(campusId, checkInState.CheckIn.CurrentFamily.Group.CampusId);


                AttendanceCode attendanceCode = null;
                DateTime       startDateTime  = Rock.RockDateTime.Now;
                DateTime       today          = startDateTime.Date;
                DateTime       tomorrow       = startDateTime.AddDays(1);

                bool reuseCodeForFamily = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
                int  securityCodeLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3;

                var attendanceCodeService = new AttendanceCodeService(rockContext);
                var attendanceService     = new AttendanceService(rockContext);
                var groupMemberService    = new GroupMemberService(rockContext);
                var personAliasService    = new PersonAliasService(rockContext);

                //This list is just for mobile check-in
                List <Attendance> attendances = new List <Attendance>();

                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))
                                    {
                                        var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                        if (primaryAlias != null)
                                        {
                                            int groupId = ActualGroupId(group.Group);
                                            // If a like attendance service exists close it before creating another one.
                                            var oldAttendance = attendanceService.Queryable()
                                                                .Where(a =>
                                                                       a.StartDateTime >= today &&
                                                                       a.StartDateTime < tomorrow &&
                                                                       a.Occurrence.LocationId == location.Location.Id &&
                                                                       a.Occurrence.ScheduleId == schedule.Schedule.Id &&
                                                                       a.Occurrence.GroupId == groupId &&
                                                                       a.PersonAlias.PersonId == person.Person.Id)
                                                                .FirstOrDefault();

                                            if (oldAttendance != null)
                                            {
                                                oldAttendance.EndDateTime = Rock.RockDateTime.Now;
                                                oldAttendance.DidAttend   = false;
                                            }
                                            var attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, groupId,
                                                                                           location.Location.Id, schedule.Schedule.Id, campusId ?? location.CampusId,
                                                                                           checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id,
                                                                                           checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id);

                                            attendance.DeviceId                 = checkInState.Kiosk.Device.Id;
                                            attendance.SearchTypeValueId        = checkInState.CheckIn.SearchType.Id;
                                            attendance.SearchValue              = checkInState.CheckIn.SearchValue;
                                            attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId;
                                            attendance.SearchResultGroupId      = family.Group.Id;
                                            attendance.AttendanceCodeId         = attendanceCode.Id;
                                            attendance.CreatedDateTime          = startDateTime;
                                            attendance.StartDateTime            = startDateTime;
                                            attendance.EndDateTime              = null;
                                            attendance.Note      = group.Notes;
                                            attendance.DidAttend = isMobile ? false : groupType.GroupType.GetAttributeValue("SetDidAttend").AsBoolean();
                                            if (isMobile)
                                            {
                                                if (groupType.GroupType.GetAttributeValue("SetDidAttend").AsBoolean())
                                                {
                                                    attendance.QualifierValueId = mobileDidAttendId;
                                                }
                                                else
                                                {
                                                    attendance.QualifierValueId = mobileNotAttendId;
                                                }
                                            }
                                            ;

                                            attendanceService.Add(attendance);
                                            attendances.Add(attendance);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (isMobile)
                {
                    var alreadyExistingMobileCheckin = MobileCheckinRecordCache.GetActiveByFamilyGroupId(checkInState.CheckIn.CurrentFamily.Group.Id);
                    if (alreadyExistingMobileCheckin != null)
                    {
                        //This should never run, it's just in case. Each family should only have 1 mobile check-in reservation.
                        MobileCheckinRecordCache.CancelReservation(alreadyExistingMobileCheckin, true);
                    }

                    campusId = RollUpToParentCampus(campusId);

                    MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext);
                    var mobileCheckinRecord = new MobileCheckinRecord
                    {
                        AccessKey             = "MCR" + Guid.NewGuid().ToString("N").Substring(0, 12),
                        ReservedUntilDateTime = Rock.RockDateTime.Now.AddMinutes(kioskType.MinutesValid ?? 10),
                        ExpirationDateTime    = Rock.RockDateTime.Now.AddMinutes((kioskType.MinutesValid ?? 10) + (kioskType.GraceMinutes ?? 60)),
                        UserName      = checkInState.CheckIn.SearchValue,
                        FamilyGroupId = checkInState.CheckIn.CurrentFamily.Group.Id,
                        CampusId      = campusId.Value
                    };

                    foreach (var attendance in attendances)
                    {
                        mobileCheckinRecord.Attendances.Add(attendance);
                    }

                    mobileCheckinRecordService.Add(mobileCheckinRecord);
                }

                rockContext.SaveChanges();
                foreach (var attendance in attendances)
                {
                    AttendanceCache.AddOrUpdate(attendance);
                }
                return(true);
            }
            errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null.");
            return(false);
        }
示例#6
0
        /// <summary>
        /// Creates the connection requests.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="campaignItem">The campaign item.</param>
        /// <returns></returns>
        private int CreateConnectionRequests(IJobExecutionContext context, CampaignItem campaignItem)
        {
            context.UpdateLastStatusMessage($"Processing create connection requests for {campaignItem.Name}");

            // Skip creating connection requests if set to "AsNeeded" and DailyLimitAssigned is 0 or null
            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                (campaignItem.DailyLimitAssigned <= 0 || campaignItem.DailyLimitAssigned == null))
            {
                return(0);
            }

            int recordsProcessed = 0;

            var rockContext = new RockContext();
            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var personAliasService           = new PersonAliasService(rockContext);
            var entitySetItemService         = new EntitySetItemService(rockContext);

            var connectionOpportunity = connectionOpportunityService.Get(campaignItem.OpportunityGuid);

            if (connectionOpportunity == null)
            {
                return(0);
            }

            // get cutoff for the last connection datetime.
            var lastConnectionDateTime = RockDateTime.Now.AddDays(-campaignItem.DaysBetweenConnection);

            // if DaysBetweenConnection is 0 then check for connection request for any time period.
            if (campaignItem.DaysBetweenConnection == default(int))
            {
                lastConnectionDateTime = DateTime.MinValue;
            }

            var entitySetItemsQry = entitySetItemService
                                    .Queryable()
                                    .Where(a => a.EntitySetId == campaignItem.EntitySetId)
                                    .OrderBy(a => a.Order);

            bool autoAssignment     = false;
            var  eligibleConnectors = new List <ConnectionConnector>();

            if (campaignItem.DailyLimitAssigned.HasValue &&
                campaignItem.DailyLimitAssigned != default(int))
            {
                autoAssignment     = true;
                eligibleConnectors = GetEligibleConnectorWithLimit(connectionOpportunity.Id, rockContext, campaignItem.DailyLimitAssigned.Value);
            }

            var connectionStatusId = GetConnectionStatus(connectionOpportunity);

            if (!connectionStatusId.HasValue)
            {
                return(0);
            }

            var entitySetItemList = entitySetItemsQry.ToList();

            foreach (var entitySetItem in entitySetItemList)
            {
                var entityItemPersonAlias = personAliasService.GetPrimaryAlias(entitySetItem.EntityId);

                int?connectorPersonId = null;
                if (autoAssignment)
                {
                    connectorPersonId = GetConnector(campaignItem, connectionOpportunity, eligibleConnectors, entityItemPersonAlias, rockContext);

                    if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded && !connectorPersonId.HasValue)
                    {
                        continue;
                    }
                }

                // double check that they haven't already been added
                var personAlreadyHasConnectionRequest = CampaignConnectionHelper.PersonAlreadyHasConnectionRequest(connectionOpportunity.Id, rockContext, lastConnectionDateTime, entitySetItem.EntityId);

                if (personAlreadyHasConnectionRequest)
                {
                    continue;
                }

                int?connectorPersonAliasId = null;
                if (connectorPersonId.HasValue)
                {
                    foreach (var connectionConnector in eligibleConnectors.Where(a => a.PersonId == connectorPersonId.Value))
                    {
                        connectorPersonAliasId       = connectionConnector.PersonAliasId;
                        connectionConnector.Current += 1;
                    }
                }

                CreateConnectionRequest(entityItemPersonAlias, campaignItem.RequestCommentsLavaTemplate, connectionOpportunity.Id, connectionStatusId, connectorPersonAliasId, rockContext);

                recordsProcessed += 1;
            }

            return(recordsProcessed);
        }
示例#7
0
        /// <summary>
        /// Creates the connection requests.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="campaignItem">The campaign item.</param>
        /// <returns></returns>
        private int CreateConnectionRequests(IJobExecutionContext context, CampaignItem campaignItem)
        {
            context.UpdateLastStatusMessage($"Processing create connection requests for {campaignItem.Name}");

            // Skip creating connection requests if set to "AsNeeded" and DailyLimitAssigned is 0 or null
            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                (campaignItem.DailyLimitAssigned <= 0 || campaignItem.DailyLimitAssigned == null))
            {
                return(0);
            }

            int recordsProcessed = 0;

            var rockContext = new RockContext();
            var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
            var personAliasService           = new PersonAliasService(rockContext);
            var connectionRequestService     = new ConnectionRequestService(rockContext);

            var connectionOpportunity = connectionOpportunityService.Get(campaignItem.OpportunityGuid);

            if (connectionOpportunity == null)
            {
                return(0);
            }

            // get cutoff for the last connection datetime.
            var lastConnectionDateTime = RockDateTime.Now.AddDays(-campaignItem.DaysBetweenConnection);

            // if DaysBetweenConnection is 0 then check for connection request for any time period.
            if (campaignItem.DaysBetweenConnection == default(int))
            {
                lastConnectionDateTime = DateTime.MinValue;
            }

            var entitySetItemService = new EntitySetItemService(rockContext);

            var entitySetItemsQry = entitySetItemService
                                    .Queryable()
                                    .Where(a => a.EntitySetId == campaignItem.EntitySetId)
                                    .OrderBy(a => a.Order);

            bool autoAssignment     = false;
            var  eligibleConnectors = new List <ConnectionConnector>();

            if (campaignItem.CreateConnectionRequestOption == CreateConnectionRequestOptions.AsNeeded &&
                campaignItem.DailyLimitAssigned.HasValue &&
                campaignItem.DailyLimitAssigned != default(int))
            {
                autoAssignment     = true;
                eligibleConnectors = GetEligibleConnectorWithLimit(connectionOpportunity.Id, rockContext, campaignItem.DailyLimitAssigned.Value);
            }

            int?connectionStatusId = connectionOpportunity.ConnectionType.ConnectionStatuses
                                     .Where(s => s.IsDefault)
                                     .Select(s => ( int? )s.Id)
                                     .FirstOrDefault();

            // If opportunity doesn't have a default status, something is wrong
            if (connectionStatusId == null)
            {
                ExceptionLogService.LogException(new Exception($"Unable to determine default connection status for {connectionOpportunity.Name} while processing campaigns", null));
                return(0);
            }

            var dayofWeek         = RockDateTime.Now.DayOfWeek;
            var entitySetItemList = entitySetItemsQry.ToList();

            foreach (var entitySetItem in entitySetItemList)
            {
                var personAlias            = personAliasService.GetPrimaryAlias(entitySetItem.EntityId);
                var defaultCampus          = personAlias.Person.GetCampus();
                int?connectorPersonAliasId = null;
                if (autoAssignment)
                {
                    int?connectorPersonId = null;
                    if (campaignItem.PreferPreviousConnector)
                    {
                        var personIds = eligibleConnectors
                                        .Where(a => a.Limit - a.Current > 0 &&
                                               (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) &&
                                               (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value)))
                                        .Select(a => a.PersonId)
                                        .ToList();

                        if (personIds.Any())
                        {
                            var person = connectionRequestService
                                         .Queryable()
                                         .Where(a => a.ConnectionOpportunityId == connectionOpportunity.Id &&
                                                a.PersonAlias.PersonId == personAlias.PersonId &&
                                                a.ConnectionState == ConnectionState.Connected &&
                                                a.ConnectorPersonAliasId.HasValue &&
                                                personIds.Contains(a.ConnectorPersonAlias.PersonId))
                                         .Select(a => a.ConnectorPersonAlias.Person)
                                         .FirstOrDefault();

                            if (person != null)
                            {
                                connectorPersonId = person.Id;
                            }
                        }
                    }

                    if (!connectorPersonId.HasValue)
                    {
                        var eligibleConnector = eligibleConnectors
                                                .Where(a => a.Limit - a.Current > 0 &&
                                                       (!a.DaysOfWeek.Any() || a.DaysOfWeek.Contains(dayofWeek)) &&
                                                       (!a.CampusId.HasValue || (a.CampusId.HasValue && defaultCampus != null && defaultCampus.Id == a.CampusId.Value)))
                                                .OrderBy(a => a.Current)     // order from least assigned to most assigned
                                                .ThenBy(x => Guid.NewGuid()) // and then randomize
                                                .FirstOrDefault();

                        if (eligibleConnector != null)
                        {
                            connectorPersonId = eligibleConnector.PersonId;
                        }
                    }

                    if (!connectorPersonId.HasValue)
                    {
                        continue;
                    }

                    foreach (var connectionConnector in eligibleConnectors.Where(a => a.PersonId == connectorPersonId.Value))
                    {
                        connectorPersonAliasId       = connectionConnector.PersonAliasId;
                        connectionConnector.Current += 1;
                    }
                }

                using (var insertRockContext = new RockContext())
                {
                    try
                    {
                        /*
                         *  3/30/2020 - NA
                         *
                         *  When setting the connection request's Requester, we have to use the PrimaryAlias
                         *  to set the connectionRequest.PersonAlias property because the ConnectionRequestChangeTransaction
                         *  https://github.com/SparkabilityGroup/Rock/blob/a556a9285b7fdfe5594441286242f4feaa5847f2/Rock/Transactions/ConnectionRequestChangeTransaction.cs#L123
                         *  (which handles triggered workflows) expects it.  Also, it needs to be tracked by
                         *  the current rockContext...
                         *
                         *  In other words, this will not work correctly:
                         *  PersonAliasId = personAlias.Id,
                         *
                         *  Reason: This plug-in cannot change Rock core assembly code.
                         */

                        var personPrimaryAlias = new PersonAliasService(insertRockContext).GetPrimaryAlias(entitySetItem.EntityId);
                        var connectionRequestActivityService = new ConnectionRequestActivityService(insertRockContext);
                        var insertConnectionRequestService   = new ConnectionRequestService(insertRockContext);

                        // double check that they haven't already been added
                        var personAlreadyHasConnectionRequest = CampaignConnectionHelper.PersonAlreadyHasConnectionRequest(connectionOpportunity.Id, rockContext, lastConnectionDateTime, entitySetItem.EntityId);

                        if (personAlreadyHasConnectionRequest)
                        {
                            continue;
                        }

                        var connectionRequest = new ConnectionRequest()
                        {
                            ConnectionOpportunityId = connectionOpportunity.Id,
                            PersonAlias             = personPrimaryAlias,
                            ConnectionState         = ConnectionState.Active,
                            ConnectorPersonAliasId  = connectorPersonAliasId,
                            CampusId           = defaultCampus?.Id,
                            ConnectionStatusId = connectionStatusId.Value,
                        };

                        if (campaignItem.RequestCommentsLavaTemplate.IsNotNullOrWhiteSpace())
                        {
                            var mergeFields = new Dictionary <string, object>();
                            mergeFields.Add("Person", personAlias.Person);
                            mergeFields.Add("Family", personAlias.Person.GetFamily());
                            connectionRequest.Comments = campaignItem.RequestCommentsLavaTemplate.ResolveMergeFields(mergeFields);
                        }

                        insertConnectionRequestService.Add(connectionRequest);

                        if (connectorPersonAliasId.HasValue)
                        {
                            var connectionActivityTypeAssignedGuid = Rock.SystemGuid.ConnectionActivityType.ASSIGNED.AsGuid();
                            int?assignedActivityId = new ConnectionActivityTypeService(rockContext).GetId(connectionActivityTypeAssignedGuid);
                            if (assignedActivityId.HasValue)
                            {
                                var connectionRequestActivity = new ConnectionRequestActivity();
                                connectionRequestActivity.ConnectionRequest        = connectionRequest;
                                connectionRequestActivity.ConnectionOpportunityId  = connectionRequest.ConnectionOpportunityId;
                                connectionRequestActivity.ConnectionActivityTypeId = assignedActivityId.Value;
                                connectionRequestActivity.ConnectorPersonAliasId   = connectorPersonAliasId;
                                connectionRequestActivityService.Add(connectionRequestActivity);
                            }
                        }

                        insertRockContext.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        // Log exception and keep on trucking.
                        var exception = new Exception($"Exception occurred trying to create connection request:{personAlias.Id}.", ex);
                        createConnectionRequestExceptions.Add(exception);
                        ExceptionLogService.LogException(exception, null);
                    }
                }

                recordsProcessed += 1;
            }

            return(recordsProcessed);
        }
        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
        }
示例#9
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;
                DateTime       startDateTime  = RockDateTime.Now;

                bool reuseCodeForFamily = GetAttributeValue(action, "ReuseCodeForFamily").AsBoolean();

                int securityCodeLength = 3;
                if (!int.TryParse(GetAttributeValue(action, "SecurityCodeLength"), out securityCodeLength))
                {
                    securityCodeLength = 3;
                }

                var attendanceCodeService = new AttendanceCodeService(rockContext);
                var attendanceService     = new AttendanceService(rockContext);
                var groupMemberService    = new GroupMemberService(rockContext);
                var personAliasService    = new PersonAliasService(rockContext);

                foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected))
                {
                    foreach (var person in family.People.Where(p => p.Selected))
                    {
                        if (reuseCodeForFamily && attendanceCode != null)
                        {
                            person.SecurityCode = attendanceCode.Code;
                        }
                        else
                        {
                            attendanceCode      = AttendanceCodeService.GetNew(securityCodeLength);
                            person.SecurityCode = attendanceCode.Code;
                        }

                        foreach (var groupType in person.GroupTypes.Where(g => g.Selected))
                        {
                            foreach (var group in groupType.Groups.Where(g => g.Selected))
                            {
                                foreach (var location in group.Locations.Where(l => l.Selected))
                                {
                                    if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn &&
                                        groupType.GroupType.DefaultGroupRoleId.HasValue &&
                                        !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any())
                                    {
                                        var groupMember = new GroupMember();
                                        groupMember.GroupId     = group.Group.Id;
                                        groupMember.PersonId    = person.Person.Id;
                                        groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value;
                                        groupMemberService.Add(groupMember);
                                    }

                                    foreach (var schedule in location.Schedules.Where(s => s.Selected))
                                    {
                                        // Only create one attendance record per day for each person/schedule/group/location
                                        var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id);
                                        if (attendance == null)
                                        {
                                            var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                            if (primaryAlias != null)
                                            {
                                                attendance = rockContext.Attendances.Create();
                                                attendance.Occurrence.LocationId = location.Location.Id;
                                                attendance.CampusId = location.CampusId;
                                                attendance.Occurrence.ScheduleId = schedule.Schedule.Id;
                                                attendance.Occurrence.GroupId    = group.Group.Id;
                                                attendance.PersonAlias           = primaryAlias;
                                                attendance.PersonAliasId         = primaryAlias.Id;
                                                attendance.DeviceId          = checkInState.Kiosk.Device.Id;
                                                attendance.SearchTypeValueId = checkInState.CheckIn.SearchType.Id;
                                                attendanceService.Add(attendance);
                                            }
                                        }

                                        attendance.AttendanceCodeId = attendanceCode.Id;
                                        attendance.StartDateTime    = startDateTime;
                                        attendance.EndDateTime      = null;
                                        attendance.DidAttend        = false;

                                        KioskLocationAttendance.AddAttendance(attendance);
                                    }
                                }
                            }
                        }
                    }
                }

                rockContext.SaveChanges();
                return(true);
            }
            errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null.");
            return(false);
        }
示例#10
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             = checkInState.CheckInType != null && checkInState.CheckInType.ReuseSameCode;
                int  securityCodeAlphaNumericLength = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaNumericLength : 3;
                int  securityCodeAlphaLength        = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeAlphaLength : 0;
                int  securityCodeNumericLength      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericLength : 0;
                bool securityCodeNumericRandom      = checkInState.CheckInType != null ? checkInState.CheckInType.SecurityCodeNumericRandom : true;


                var attendanceCodeService = new AttendanceCodeService(rockContext);
                var attendanceService     = new AttendanceService(rockContext);
                var groupMemberService    = new GroupMemberService(rockContext);
                var personAliasService    = new PersonAliasService(rockContext);
                var attendanceRecords     = new List <Attendance>();

                checkInState.Messages.Clear();

                var family = checkInState.CheckIn.CurrentFamily;
                if (family != null)
                {
                    var currentOccurences = new List <OccurenceRecord>();
                    foreach (var person in family.GetPeople(true))
                    {
                        if (reuseCodeForFamily && attendanceCode != null)
                        {
                            person.SecurityCode = attendanceCode.Code;
                        }
                        else
                        {
                            attendanceCode      = AttendanceCodeService.GetNew(securityCodeAlphaNumericLength, securityCodeAlphaLength, securityCodeNumericLength, securityCodeNumericRandom);
                            person.SecurityCode = attendanceCode.Code;
                        }

                        foreach (var groupType in person.GetGroupTypes(true))
                        {
                            foreach (var group in groupType.GetGroups(true))
                            {
                                if (groupType.GroupType.AttendanceRule == AttendanceRule.AddOnCheckIn &&
                                    groupType.GroupType.DefaultGroupRoleId.HasValue &&
                                    !groupMemberService.GetByGroupIdAndPersonId(group.Group.Id, person.Person.Id, true).Any())
                                {
                                    var groupMember = new GroupMember();
                                    groupMember.GroupId     = group.Group.Id;
                                    groupMember.PersonId    = person.Person.Id;
                                    groupMember.GroupRoleId = groupType.GroupType.DefaultGroupRoleId.Value;
                                    groupMemberService.Add(groupMember);
                                }

                                foreach (var location in group.GetLocations(true))
                                {
                                    bool isCheckedIntoLocation = false;
                                    foreach (var schedule in location.GetSchedules(true))
                                    {
                                        var startDateTime = schedule.CampusCurrentDateTime;

                                        // If we're enforcing strict location thresholds, then before we create an attendance record
                                        // we need to check the location-schedule's current count.
                                        if (GetAttributeValue(action, "EnforceStrictLocationThreshold").AsBoolean() && location.Location.SoftRoomThreshold.HasValue)
                                        {
                                            var thresHold = location.Location.SoftRoomThreshold.Value;
                                            if (checkInState.ManagerLoggedIn && location.Location.FirmRoomThreshold.HasValue && location.Location.FirmRoomThreshold.Value > location.Location.SoftRoomThreshold.Value)
                                            {
                                                thresHold = location.Location.FirmRoomThreshold.Value;
                                            }

                                            var currentOccurence = GetCurrentOccurence(currentOccurences, location, schedule, startDateTime.Date);

                                            // The totalAttended is the number of people still checked in (not people who have been checked-out)
                                            // not counting the current person who may already be checked in,
                                            // + the number of people we have checked in so far (but haven't been saved yet).
                                            var attendanceQry = attendanceService.GetByDateOnLocationAndSchedule(startDateTime.Date, location.Location.Id, schedule.Schedule.Id)
                                                                .AsNoTracking()
                                                                .Where(a => a.EndDateTime == null);

                                            // Only process if the current person is NOT already checked-in to this location and schedule
                                            if (!attendanceQry.Where(a => a.PersonAlias.PersonId == person.Person.Id).Any())
                                            {
                                                var totalAttended = attendanceQry.Count() + (currentOccurence == null ? 0 : currentOccurence.Count);

                                                // If over capacity, remove the schedule and add a warning message.
                                                if (totalAttended >= thresHold)
                                                {
                                                    // Remove the schedule since the location was full for this schedule.
                                                    location.Schedules.Remove(schedule);

                                                    var message = new CheckInMessage()
                                                    {
                                                        MessageType = MessageType.Warning
                                                    };

                                                    var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null);
                                                    mergeFields.Add("Person", person.Person);
                                                    mergeFields.Add("Group", group.Group);
                                                    mergeFields.Add("Location", location.Location);
                                                    mergeFields.Add("Schedule", schedule.Schedule);
                                                    message.MessageText = GetAttributeValue(action, "NotChecked-InMessageFormat").ResolveMergeFields(mergeFields);

                                                    // Now add it to the check-in state message list for others to see.
                                                    checkInState.Messages.Add(message);
                                                    continue;
                                                }
                                                else
                                                {
                                                    // Keep track of anyone who was checked in so far.
                                                    if (currentOccurence == null)
                                                    {
                                                        currentOccurence = new OccurenceRecord()
                                                        {
                                                            Date       = startDateTime.Date,
                                                            LocationId = location.Location.Id,
                                                            ScheduleId = schedule.Schedule.Id
                                                        };
                                                        currentOccurences.Add(currentOccurence);
                                                    }

                                                    currentOccurence.Count += 1;
                                                }
                                            }
                                        }

                                        // Only create one attendance record per day for each person/schedule/group/location
                                        var attendance = attendanceService.Get(startDateTime, location.Location.Id, schedule.Schedule.Id, group.Group.Id, person.Person.Id);
                                        if (attendance == null)
                                        {
                                            var primaryAlias = personAliasService.GetPrimaryAlias(person.Person.Id);
                                            if (primaryAlias != null)
                                            {
                                                attendance = attendanceService.AddOrUpdate(primaryAlias.Id, startDateTime.Date, group.Group.Id,
                                                                                           location.Location.Id, schedule.Schedule.Id, location.CampusId,
                                                                                           checkInState.Kiosk.Device.Id, checkInState.CheckIn.SearchType.Id,
                                                                                           checkInState.CheckIn.SearchValue, family.Group.Id, attendanceCode.Id);

                                                attendance.PersonAlias = primaryAlias;
                                            }
                                        }

                                        attendance.DeviceId                 = checkInState.Kiosk.Device.Id;
                                        attendance.SearchTypeValueId        = checkInState.CheckIn.SearchType.Id;
                                        attendance.SearchValue              = checkInState.CheckIn.SearchValue;
                                        attendance.CheckedInByPersonAliasId = checkInState.CheckIn.CheckedInByPersonAliasId;
                                        attendance.SearchResultGroupId      = family.Group.Id;
                                        attendance.AttendanceCodeId         = attendanceCode.Id;
                                        attendance.StartDateTime            = startDateTime;
                                        attendance.EndDateTime              = null;
                                        attendance.DidAttend                = true;
                                        attendance.Note = group.Notes;

                                        KioskLocationAttendance.AddAttendance(attendance);
                                        isCheckedIntoLocation = true;

                                        // Keep track of attendance (Ids) for use by other actions later in the workflow pipeline
                                        attendanceRecords.Add(attendance);
                                    }

                                    // If the person was NOT checked into the location for any schedule then remove the location
                                    if (!isCheckedIntoLocation)
                                    {
                                        group.Locations.Remove(location);
                                    }
                                }
                            }
                        }
                    }
                }

                rockContext.SaveChanges();

                // Now that the records are persisted, take the Ids and save them to the temp CheckInFamliy object
                family.AttendanceIds = attendanceRecords.Select(a => a.Id).ToList();
                attendanceRecords    = null;

                return(true);
            }

            return(false);
        }