Пример #1
0
        /// <summary>
        /// Process if the user should be redirected.
        /// </summary>
        protected void ProcessRedirect()
        {
            bool enableReverseLookup = GetAttributeValue("EnableReverseLookup").AsBoolean(false);

            using (var rockContext = new RockContext())
            {
                var deviceService = new DeviceService(rockContext);
                var guids         = GetAttributeValue("AllowedDeviceTypes")
                                    .Split(',')
                                    .Select(g => g.Trim())
                                    .Where(g => !string.IsNullOrEmpty(g));

                foreach (var guid in guids)
                {
                    var checkInDeviceTypeId = DefinedValueCache.Read(guid).Id;
                    var device = deviceService.GetByIPAddress(RockPage.GetClientIpAddress(), checkInDeviceTypeId, !enableReverseLookup);

                    if (device != null)
                    {
                        nbRedirect.Text    = string.Empty;
                        nbRedirect.Visible = false;

                        return;
                    }
                }

                Redirect();
            }
        }
Пример #2
0
        /// <summary>
        /// Attempts to match a known kiosk based on the IP address of the client.
        /// </summary>
        private void AttemptKioskMatchByIpOrName()
        {
            // match kiosk by ip/name.
            string ipAddress       = RockPage.GetClientIpAddress();
            bool   lookupKioskName = GetAttributeValue("EnableReverseLookup").AsBoolean(false);

            var rockContext         = new RockContext();
            var checkInDeviceTypeId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.DEVICE_TYPE_CHECKIN_KIOSK).Id;
            var device = new DeviceService(rockContext).GetByIPAddress(ipAddress, checkInDeviceTypeId, lookupKioskName);

            string hostName       = string.Empty;
            string deviceLocation = string.Empty;

            try
            {
                hostName = Dns.GetHostEntry(ipAddress).HostName;
            }
            catch (System.Net.Sockets.SocketException)
            {
                hostName = "Unknown";
            }

            if (device != null)
            {
                var location = device.Locations.FirstOrDefault();
                if (location != null)
                {
                    deviceLocation = location.Name;
                }

                ClearMobileCookie();
                CurrentKioskId = device.Id;
            }
            else
            {
                maAlert.Show("This device has not been set up for check-in.", ModalAlertType.Alert);
                lbOk.Text    = @"<span class='fa fa-refresh' />";
                lbOk.Enabled = false;
            }

            lblInfo.Text = string.Format("Device IP: {0} &nbsp;&nbsp;&nbsp;&nbsp; Name: {1} &nbsp;&nbsp;&nbsp;&nbsp; Location: {2}", ipAddress, hostName, deviceLocation);
            pnlContent.Update();
            pnlHeader.Update();
        }
Пример #3
0
        /// <summary>
        /// Redirect the user to the Redirect Page. If they are an Administrator then
        /// show a warning with a hyperlink to where they would be redirected to.
        /// </summary>
        void Redirect()
        {
            var target = new PageReference(GetAttributeValue("RedirectPage"));

            if (UserCanAdministrate)
            {
                PageReference self = new PageReference(RockPage.PageId);

                nbRedirect.Text = string.Format(
                    "If you were not an Administrator you would have been redirected to <a href=\"{0}\">{0}</a> because your IP address {1} does not match an allowed device.",
                    target.BuildUrl(), RockPage.GetClientIpAddress());
                nbRedirect.Visible = true;
            }
            else
            {
                Response.Redirect(target.BuildUrl());
                Response.End();
            }
        }
Пример #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>
        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>
        /// Further configure this info object based on the options specified by the caller, then enqueue it to be bulk inserted.
        /// </summary>
        /// <param name="queue">The <see cref="ConcurrentQueue{InterationInfo}"/> into which this info object should be enqueued.</param>
        public void Initialize(ConcurrentQueue <InteractionTransactionInfo> queue)
        {
            RockPage    rockPage = null;
            HttpRequest request  = null;

            if (this.GetValuesFromHttpRequest)
            {
                try
                {
                    rockPage = HttpContext.Current.Handler as RockPage;
                }
                catch
                {
                    rockPage = null;
                }

                try
                {
                    if (rockPage != null)
                    {
                        request = rockPage.Request;
                    }
                    else if (HttpContext.Current != null)
                    {
                        request = HttpContext.Current.Request;
                    }
                }
                catch
                {
                    // Intentionally ignore exception (.Request will throw an exception instead of simply returning null if it isn't available).
                }
            }

            // Fall back to values from the HTTP request if specified by the caller AND the values weren't explicitly set on the info object:
            // (The rockPage and request variables will only be defined if this.GetValuesFromHttpRequest was true.)

            this.InteractionData = this.InteractionData ?? request?.Url.ToString();
            this.UserAgent       = this.UserAgent ?? request?.UserAgent;

            try
            {
                this.IPAddress = this.IPAddress ?? RockPage.GetClientIpAddress();
            }
            catch
            {
                this.IPAddress = string.Empty;
            }

            this.BrowserSessionId = this.BrowserSessionId ?? rockPage?.Session["RockSessionId"]?.ToString().AsGuidOrNull();

            this.PersonAliasId = this.PersonAliasId ?? rockPage?.CurrentPersonAliasId;

            // Make sure we don't exceed this field's character limit.
            this.InteractionOperation = EnforceLengthLimitation(this.InteractionOperation, 25);

            if (this.InteractionSummary.IsNullOrWhiteSpace())
            {
                // If InteractionSummary was not specified, use the Page title.
                var title = string.Empty;
                if (rockPage != null)
                {
                    if (rockPage.BrowserTitle.IsNotNullOrWhiteSpace())
                    {
                        title = rockPage.BrowserTitle;
                    }
                    else
                    {
                        title = rockPage.PageTitle;
                    }
                }

                // Remove the site name from the title.
                if (title?.Contains("|") == true)
                {
                    title = title.Substring(0, title.LastIndexOf('|')).Trim();
                }

                this.InteractionSummary = title;
            }

            // Make sure we don't exceed these fields' character limit.
            this.InteractionSummary               = EnforceLengthLimitation(this.InteractionSummary, 500);
            this.InteractionChannelCustom1        = EnforceLengthLimitation(this.InteractionChannelCustom1, 500);
            this.InteractionChannelCustom2        = EnforceLengthLimitation(this.InteractionChannelCustom2, 2000);
            this.InteractionChannelCustomIndexed1 = EnforceLengthLimitation(this.InteractionChannelCustomIndexed1, 500);
            this.InteractionSource   = EnforceLengthLimitation(this.InteractionSource, 25);
            this.InteractionMedium   = EnforceLengthLimitation(this.InteractionMedium, 25);
            this.InteractionCampaign = EnforceLengthLimitation(this.InteractionCampaign, 50);
            this.InteractionContent  = EnforceLengthLimitation(this.InteractionContent, 50);
            this.InteractionTerm     = EnforceLengthLimitation(this.InteractionTerm, 50);

            // Get existing (or create new) interaction channel and interaction component for this interaction.
            if (this.InteractionChannelId == default)
            {
                this.InteractionChannelId = InteractionChannelCache.GetChannelIdByTypeIdAndEntityId(this.ChannelTypeMediumValueId, this.ChannelEntityId, this.ChannelName, this.ComponentEntityTypeId, this.InteractionEntityTypeId);
            }

            this.InteractionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(this.InteractionChannelId, this.ComponentEntityId, this.ComponentName);

            queue.Enqueue(this);
        }
Пример #6
0
        /// <summary>
        /// Attempts the authentication.
        /// </summary>
        private void AttemptAuthentication(string authCode)
        {
            pnlAuthenticate.Visible = false;
            pnlSuccess.Visible      = true;

            var codeExpirationDuration = GetAttributeValue(AttributeKey.CodeExpirationDuration).AsInteger();
            var codeExpirationDateTime = RockDateTime.Now.AddMinutes(codeExpirationDuration * -1);

            // Get site
            var siteId = GetAttributeValue(AttributeKey.Site).AsIntegerOrNull();

            if (siteId.HasValue)
            {
                var site = SiteCache.Get(siteId.Value);
                siteId = site.Id;
            }

            // Get matching remote authenication record
            var rockContext = new RockContext();
            var remoteAuthenticationService = new RemoteAuthenticationSessionService(rockContext);

            // Create a fallback date to eliminate very old sessions. We want to be able to tell someone
            // that the code they have has expired so we can't use the expiration date, we need a date older
            // than that.
            var expirationWindowDate = codeExpirationDateTime.AddHours(-2);

            var authSession = remoteAuthenticationService.Queryable()
                              .Where(s => s.SiteId == siteId &&
                                     s.Code == authCode &&
                                     s.AuthorizedPersonAliasId == null &&
                                     s.SessionStartDateTime > expirationWindowDate)
                              .FirstOrDefault();

            // Check for code that does not exist
            if (authSession == null)
            {
                nbAuthenticationMessages.Text = "The code provided is not valid. Please confirm that you have correctly entered the code.";
                nbAuthenticationMessages.NotificationBoxType = NotificationBoxType.Warning;
                nbAuthenticationMessages.Visible             = true;
                return;
            }

            // Check for expired session
            if (authSession.SessionStartDateTime < codeExpirationDateTime)
            {
                nbAuthenticationMessages.Text = "The code you provided has expired. Please create a new new code and try again.";
                nbAuthenticationMessages.NotificationBoxType = NotificationBoxType.Warning;
                nbAuthenticationMessages.Visible             = true;
                return;
            }

            // Process authentication
            authSession.AuthorizedPersonAliasId      = CurrentPersonAliasId;
            authSession.SessionAuthenticatedDateTime = RockDateTime.Now;
            authSession.AuthenticationIpAddress      = RockPage.GetClientIpAddress();

            rockContext.SaveChanges();

            // Show success message
            pnlAuthenticate.Visible = false;
            pnlSuccess.Visible      = true;

            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, null, new Rock.Lava.CommonMergeFieldsOptions {
                GetLegacyGlobalMergeFields = false
            });

            lSuccessContent.Text = GetAttributeValue(AttributeKey.SuccessMessage).ResolveMergeFields(mergeFields);
        }
Пример #7
0
        /// <summary>
        /// Initializes this instance.
        /// </summary>
        private void Initialize()
        {
            RockPage rockPage;

            try
            {
                rockPage = HttpContext.Current.Handler as RockPage;
            }
            catch
            {
                rockPage = null;
            }

            HttpRequest request = null;

            try
            {
                if (rockPage != null)
                {
                    request = rockPage.Request;
                }
                else if (HttpContext.Current != null)
                {
                    request = HttpContext.Current.Request;
                }
            }
            catch
            {
                // intentionally ignore exception (.Request will throw an exception instead of simply returning null if it isn't available)
            }

            if (request == null)
            {
                _logInteraction = false;
                return;
            }

            _userAgent = request.UserAgent;
            _url       = request.Url.ToString();
            try
            {
                _ipAddress = RockPage.GetClientIpAddress();
            }
            catch
            {
                _ipAddress = "";
            }

            if (rockPage != null)
            {
                _browserSessionId    = rockPage.Session["RockSessionID"]?.ToString().AsGuidOrNull();
                CurrentPersonAliasId = rockPage.CurrentPersonAliasId;

                var title = string.Empty;
                if (rockPage.BrowserTitle.IsNotNullOrWhiteSpace())
                {
                    title = rockPage.BrowserTitle;
                }
                else
                {
                    title = rockPage.PageTitle;
                }

                // remove site name from browser title
                if (title?.Contains("|") == true)
                {
                    title = title.Substring(0, title.LastIndexOf('|')).Trim();
                }

                InteractionSummary = title;
            }

            _interactionDateTime = RockDateTime.Now;
        }
Пример #8
0
        /// <summary>
        /// Pray Request.
        /// </summary>
        private void PrayRequest(int prayerRequestId)
        {
            var           rockContext = new RockContext();
            var           service     = new PrayerRequestService(rockContext);
            var           flagLimit   = GetAttributeValue(AttributeKey.FlagLimit).AsIntegerOrNull() ?? 1;
            PrayerRequest request     = service.Get(prayerRequestId);

            if (request != null)
            {
                request.PrayerCount = (request.PrayerCount ?? 0) + 1;
                rockContext.SaveChanges();

                StartWorkflow(request, rockContext, AttributeKey.PrayedWorkflow);
                PrayerRequestService.EnqueuePrayerInteraction(request, CurrentPerson, PageCache.Layout.Site.Name, Request.UserAgent, RockPage.GetClientIpAddress(), RockPage.Session["RockSessionId"]?.ToString().AsGuidOrNull());
            }
        }
Пример #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)
            {
                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;

            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, "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 currentOccurrence = GetCurrentOccurrence(currentOccurrences, 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() + (currentOccurrence == null ? 0 : currentOccurrence.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 (currentOccurrence == null)
                                                {
                                                    currentOccurrence = new OccurrenceRecord()
                                                    {
                                                        Date       = startDateTime.Date,
                                                        LocationId = location.Location.Id,
                                                        ScheduleId = schedule.Schedule.Id
                                                    };
                                                    currentOccurrences.Add(currentOccurrence);
                                                }

                                                currentOccurrence.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.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.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();
            family.AttendanceCheckinSessionGuid = attendanceCheckInSession.Guid;
            attendanceRecords = null;

            return(true);
        }
Пример #10
0
        /// <summary>
        /// Displays the details for a single, given prayer request.
        /// </summary>
        /// <param name="prayerRequest">The prayer request.</param>
        /// <param name="rockContext">The rock context.</param>
        private void ShowPrayerRequest(PrayerRequest prayerRequest, RockContext rockContext)
        {
            pnlPrayer.Visible = true;

            prayerRequest.PrayerCount = (prayerRequest.PrayerCount ?? 0) + 1;
            hlblPrayerCountTotal.Text = prayerRequest.PrayerCount.ToString() + " team prayers";
            hlblUrgent.Visible        = prayerRequest.IsUrgent ?? false;

            if (CampusCache.All(false).Count() > 1)
            {
                hlblCampus.Text = prayerRequest.CampusId.HasValue ? prayerRequest.Campus.Name : string.Empty;
            }

            hlblCategory.Text = prayerRequest.Category.Name;
            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new Rock.Lava.CommonMergeFieldsOptions {
                GetLegacyGlobalMergeFields = false
            });

            // need to load attributes so that lava can loop thru PrayerRequest.Attributes
            prayerRequest.LoadAttributes();

            // Filter to only show attribute / attribute values that the person is authorized to view.
            var excludeForView = prayerRequest.Attributes.Where(a => !a.Value.IsAuthorized(Authorization.VIEW, this.CurrentPerson)).Select(a => a.Key).ToList();

            prayerRequest.Attributes      = prayerRequest.Attributes.Where(a => !excludeForView.Contains(a.Key)).ToDictionary(k => k.Key, k => k.Value);
            prayerRequest.AttributeValues = prayerRequest.AttributeValues.Where(av => !excludeForView.Contains(av.Key)).ToDictionary(k => k.Key, k => k.Value);

            mergeFields.Add("PrayerRequest", prayerRequest);
            string prayerPersonLava  = this.GetAttributeValue(AttributeKey.PrayerPersonLava);
            string prayerDisplayLava = this.GetAttributeValue(AttributeKey.PrayerDisplayLava);

            lPersonLavaOutput.Text = prayerPersonLava.ResolveMergeFields(mergeFields);
            lPrayerLavaOutput.Text = prayerDisplayLava.ResolveMergeFields(mergeFields);

            pnlPrayerComments.Visible = prayerRequest.AllowComments ?? false;
            if (notesComments.Visible)
            {
                notesComments.NoteOptions.EntityId = prayerRequest.Id;
            }

            CurrentPrayerRequestId = prayerRequest.Id;

            if (GetAttributeValue(AttributeKey.CreateInteractionsForPrayers).AsBoolean())
            {
                PrayerRequestService.EnqueuePrayerInteraction(prayerRequest, CurrentPerson, PageCache.Layout.Site.Name, Request.UserAgent, RockPage.GetClientIpAddress(), RockPage.Session["RockSessionId"]?.ToString().AsGuidOrNull());
            }

            try
            {
                // save because the prayer count was just modified.
                rockContext.SaveChanges();
            }
            catch (Exception ex)
            {
                ExceptionLogService.LogException(ex, Context, this.RockPage.PageId, this.RockPage.Site.Id, CurrentPersonAlias);
            }
        }