public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var analog = ( CheckInStateAnalog )serializer.Deserialize(reader, typeof(CheckInStateAnalog)); var localkey = analog.LocalKey; var memoryAnalog = CheckInStateSessionManager.Get(localkey); if (memoryAnalog != null) { //We have the state in memory analog = memoryAnalog; } else { //We have to recreate the state from our data HydrateStatus(analog.CheckIn); } var state = new CheckInState(analog.DeviceId, analog.CheckinTypeId, analog.ConfiguredGroupTypes); state.CheckInType = new CheckinType(analog.CheckinTypeId ?? 0); state.CheckIn = analog.CheckIn; state.ManagerLoggedIn = analog.ManagerLoggedIn; state.Messages = analog.Messages; return(state); }
/// <summary> /// Creates a label printer object that will process labels upon creation and contains action to print over network or recieve javascript for usb printing /// </summary> /// <param name="CurrentCheckinState"></param> /// <param name="Request"></param> public LabelPrinter(CheckInState CurrentCheckinState, HttpRequest Request) { _currentCheckinState = CurrentCheckinState; _request = Request; _labels = new List <CheckInLabel>(); ProcessLabels(); }
public HttpResponseMessage KioskStatus(int param) { var kioskType = new KioskTypeService(new RockContext()).Get(param); var Session = HttpContext.Current.Session; if (Session["CheckInState"] != null) { CurrentCheckInState = Session["CheckInState"] as CheckInState; } else { return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, new Dictionary <string, bool> { { "active", false } })); } if (kioskType == null || CurrentCheckInState == null || !kioskType.IsOpen() || CurrentCheckInState.Kiosk.FilteredGroupTypes(CurrentCheckInState.ConfiguredGroupTypes).Count == 0 || !CurrentCheckInState.Kiosk.HasLocations(CurrentCheckInState.ConfiguredGroupTypes)) { return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, new Dictionary <string, bool> { { "active", false } })); } return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, new Dictionary <string, bool> { { "active", true } })); }
/// <summary> /// Creates a label printer object that will process labels upon creation and contains action to print over network or recieve javascript for usb printing /// </summary> /// <param name="CurrentCheckinState"></param> /// <param name="Request"></param> public LabelPrinter(CheckInState currentCheckinState, HttpRequest request) { CheckInState = currentCheckinState; Request = request; Labels = new List <CheckInLabel>(); ProcessLabels(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!Page.IsPostBack) { var CurrentKioskId = ( int )Session["CheckInKioskId"]; List <int> CheckInGroupTypeIds = (List <int>)Session["CheckInGroupTypeIds"]; CurrentCheckInState = new CheckInState(CurrentKioskId, null, CheckInGroupTypeIds); CurrentCheckInState.CheckIn.UserEnteredSearch = true; CurrentCheckInState.CheckIn.ConfirmSingleFamily = true; CurrentCheckInState.CheckIn.SearchType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_PHONE_NUMBER); Random rnd = new Random(); StringBuilder output = new StringBuilder("Search Results:<hr>"); Stopwatch sw = new Stopwatch(); int count = 0; for (var i = 0; i < 10; i++) { var searchString = LongRandom(0000, 9999999999, rnd); if (i % 2 == 0) { searchString = searchString.Substring(0, 4); } CurrentCheckInState.CheckIn.SearchValue = searchString; output.Append("<br>Searched: " + searchString); sw.Reset(); sw.Start(); List <string> errors = new List <string>(); string workflowActivity = GetAttributeValue("WorkflowActivity"); if (string.IsNullOrWhiteSpace(workflowActivity)) { ltErrors.Text = "Block not configured"; return; } try { bool test = ProcessActivity(workflowActivity, out errors); count++; } catch (Exception ex) { ltErrors.Text = "Error:" + ex.Message; return; } sw.Stop(); output.Append(" in " + sw.ElapsedMilliseconds + "ms"); } ltErrors.Text = output.ToString(); ScriptManager.RegisterStartupScript(upContent, upContent.GetType(), "reload", "reload();", true); } }
public HttpResponseMessage Family(string param) { try { var Session = HttpContext.Current.Session; CurrentKioskId = ( int )Session["CheckInKioskId"]; Guid blockGuid = ( Guid )Session["BlockGuid"]; List <int> CheckInGroupTypeIds = (List <int>)Session["CheckInGroupTypeIds"]; CurrentCheckInState = new CheckInState(CurrentKioskId, null, CheckInGroupTypeIds); CurrentCheckInState.CheckIn.UserEnteredSearch = true; CurrentCheckInState.CheckIn.ConfirmSingleFamily = true; CurrentCheckInState.CheckIn.SearchType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_PHONE_NUMBER); CurrentCheckInState.CheckIn.SearchValue = param; var rockContext = new Rock.Data.RockContext(); var block = BlockCache.Read(blockGuid, rockContext); string workflowActivity = block.GetAttributeValue("WorkflowActivity"); Guid? workflowGuid = block.GetAttributeValue("WorkflowType").AsGuidOrNull(); List <string> errors; var workflowTypeService = new WorkflowTypeService(rockContext); var workflowService = new WorkflowService(rockContext); var workflowType = workflowTypeService.Queryable("ActivityTypes") .Where(w => w.Guid.Equals(workflowGuid.Value)) .FirstOrDefault(); var CurrentWorkflow = Rock.Model.Workflow.Activate(workflowType, CurrentCheckInState.Kiosk.Device.Name, rockContext); var activityType = workflowType.ActivityTypes.Where(a => a.Name == workflowActivity).FirstOrDefault(); if (activityType != null) { WorkflowActivity.Activate(activityType, CurrentWorkflow, rockContext); if (workflowService.Process(CurrentWorkflow, CurrentCheckInState, out errors)) { // Keep workflow active for continued processing CurrentWorkflow.CompletedDateTime = null; SaveState(Session); List <CheckInFamily> families = CurrentCheckInState.CheckIn.Families; families = families.OrderBy(f => f.Caption).ToList(); return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, families)); } } else { return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, string.Format("Workflow type does not have a '{0}' activity type", workflowActivity))); } return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, String.Join("\n", errors))); } catch (Exception ex) { ExceptionLogService.LogException(ex, HttpContext.Current); return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden, "Forbidden")); } }
private void SaveState(HttpSessionState Session, CheckInState currentCheckInState) { if (Session != null) { if (currentCheckInState != null) { Session["CheckInState"] = currentCheckInState; } else { Session.Remove("CheckInState"); } } }
private void ActivateCheckIn() { CurrentCheckInState = new CheckInState(LocalDeviceConfig.CurrentKioskId.Value, LocalDeviceConfig.CurrentCheckinTypeId, LocalDeviceConfig.CurrentGroupTypeIds); var userloginCheckinSearchValue = DefinedValueCache.Get(org.secc.FamilyCheckin.Utilities.Constants.CHECKIN_SEARCH_TYPE_USERLOGIN); CurrentCheckInState.CheckIn.SearchType = userloginCheckinSearchValue; CurrentCheckInState.CheckIn.SearchValue = currentUser.UserName; Session["BlockGuid"] = BlockCache.Guid; SaveState(); pnlSelectCampus.Visible = false; pnlLoading.Visible = true; var nextpageUrl = LinkedPageUrl("NextPage"); ScriptManager.RegisterStartupScript(upContent, upContent.GetType(), "Load", "processMobileCheckin('" + nextpageUrl + "')", true); }
private void addLabel(CheckInLabel checkInLabel, CheckInState checkInState, CheckInGroupType groupType, CheckInGroup group, RockContext rockContext) { var PrinterIPs = new Dictionary <int, string>(); if (checkInLabel.PrintTo == PrintTo.Default) { checkInLabel.PrintTo = groupType.GroupType.AttendancePrintTo; } else if (checkInLabel.PrintTo == PrintTo.Location && group.Locations.Any()) { var deviceId = group.Locations.FirstOrDefault().Location.PrinterDeviceId; if (deviceId != null) { checkInLabel.PrinterDeviceId = deviceId; } } else { var device = checkInState.Kiosk.Device; if (device != null) { checkInLabel.PrinterDeviceId = device.PrinterDeviceId; } } if (checkInLabel.PrinterDeviceId.HasValue) { if (PrinterIPs.ContainsKey(checkInLabel.PrinterDeviceId.Value)) { checkInLabel.PrinterAddress = PrinterIPs[checkInLabel.PrinterDeviceId.Value]; } else { var printerDevice = new DeviceService(rockContext).Get(checkInLabel.PrinterDeviceId.Value); if (printerDevice != null) { PrinterIPs.Add(printerDevice.Id, printerDevice.IPAddress); checkInLabel.PrinterAddress = printerDevice.IPAddress; } } } groupType.Labels.Insert(0, checkInLabel); }
/// <summary> /// Enforces the strict location threshold by removing attendances that would have ended up going into full location+schedules. /// Note: The is also checked earlier in the check-in process, so this catches ones that might have just gotten full in the last few seconds. /// </summary> /// <param name="action">The action.</param> /// <param name="checkInState">State of the check in.</param> /// <param name="attendanceService">The attendance service.</param> /// <param name="currentOccurrences">The current occurrences.</param> /// <param name="person">The person.</param> /// <param name="group">The group.</param> /// <param name="location">The location.</param> /// <param name="schedule">The schedule.</param> /// <param name="startDateTime">The start date time.</param> private void EnforceStrictLocationThreshold(WorkflowAction action, CheckInState checkInState, AttendanceService attendanceService, List <OccurrenceRecord> currentOccurrences, CheckInPerson person, CheckInGroup group, CheckInLocation location, CheckInSchedule schedule, DateTime startDateTime) { 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(MergeFieldKey.Person, person.Person); mergeFields.Add(MergeFieldKey.Group, group.Group); mergeFields.Add(MergeFieldKey.Location, location.Location); mergeFields.Add(MergeFieldKey.Schedule, schedule.Schedule); message.MessageText = GetAttributeValue(action, AttributeKey.NotCheckedInMessageFormat).ResolveMergeFields(mergeFields); // Now add it to the check-in state message list for others to see. checkInState.Messages.Add(message); return; } 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; } } }
/// <summary> /// Loads the person schedules. /// </summary> /// <param name="person">The person.</param> /// <param name="attendanceScheduledLookup">The attendance scheduled lookup.</param> /// <param name="kioskGroupTypeLookup">The kiosk group type lookup.</param> /// <param name="loadSelectedOnly">if set to <c>true</c> [load selected only].</param> /// <param name="remove">if set to <c>true</c> [remove], schedule will be removed vs marked excluded when doesn't meet requirements</param> /// <param name="checkInState">State of the check in.</param> private void LoadPersonSchedules(CheckInPerson person, List <PersonAttendanceScheduled> attendanceScheduledLookup, Dictionary <int, KioskGroupType> kioskGroupTypeLookup, bool loadSelectedOnly, bool remove, CheckInState checkInState) { var personGroups = person.GetGroupTypes(loadSelectedOnly).SelectMany(gt => gt.GetGroups(loadSelectedOnly)).ToList(); foreach (var group in personGroups) { var kioskGroup = kioskGroupTypeLookup.GetValueOrNull(group.Group.GroupTypeId)?.KioskGroups?.Where(g => g.Group.Id == group.Group.Id && g.IsCheckInActive) .FirstOrDefault(); if (kioskGroup == null) { continue; } var groupType = GroupTypeCache.Get(group.Group.GroupTypeId); foreach (var location in group.GetLocations(loadSelectedOnly)) { var kioskLocation = kioskGroup.KioskLocations .Where(l => l.Location.Id == location.Location.Id && l.IsCheckInActive) .FirstOrDefault(); if (kioskLocation == null) { continue; } foreach (var kioskSchedule in kioskLocation.KioskSchedules.Where(s => s.IsCheckInActive)) { bool?personIsScheduled = null; var attendanceRecordRequiredForCheckIn = group.Group.AttendanceRecordRequiredForCheckIn; // if the groupType currently doesn't have scheduling enabled, ignore the group's AttendanceRecordRequiredForCheckIn setting, and just have it be ScheduleNotRequired if (groupType.IsSchedulingEnabled == false) { attendanceRecordRequiredForCheckIn = AttendanceRecordRequiredForCheckIn.ScheduleNotRequired; } // if ScheduleRequired or PreSelect, we'll need to see if the person is scheduled if (group.Group.AttendanceRecordRequiredForCheckIn != AttendanceRecordRequiredForCheckIn.ScheduleNotRequired) { personIsScheduled = attendanceScheduledLookup?.Any(a => a.PersonId == person.Person.Id && a.GroupId == group.Group.Id && a.LocationId == location.Location.Id && a.ScheduleId == kioskSchedule.Schedule.Id); } bool excludeSchedule = false; if (group.Group.AttendanceRecordRequiredForCheckIn == AttendanceRecordRequiredForCheckIn.ScheduleRequired) { if (personIsScheduled != true) { // don't add to the person's available schedules excludeSchedule = true; } } bool preSelectForOccurrence = false; if (group.Group.AttendanceRecordRequiredForCheckIn == AttendanceRecordRequiredForCheckIn.PreSelect) { preSelectForOccurrence = personIsScheduled == true; } location.PreSelected = preSelectForOccurrence; if (excludeSchedule && remove) { // the schedule doesn't meet requirements, and the option for Excluding vs Removing is remove, so don't add it continue; } if (!location.Schedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id)) { var checkInSchedule = new CheckInSchedule(); checkInSchedule.Schedule = kioskSchedule.Schedule.Clone(false); checkInSchedule.CampusId = kioskSchedule.CampusId; checkInSchedule.StartTime = kioskSchedule.StartTime; checkInSchedule.PreSelected = preSelectForOccurrence; checkInSchedule.ExcludedByFilter = excludeSchedule; location.Schedules.Add(checkInSchedule); } if (checkInState.CheckInType?.TypeOfCheckin == TypeOfCheckin.Family && !person.PossibleSchedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id)) { var checkInSchedule = new CheckInSchedule(); checkInSchedule.Schedule = kioskSchedule.Schedule.Clone(false); checkInSchedule.CampusId = kioskSchedule.CampusId; checkInSchedule.StartTime = kioskSchedule.StartTime; checkInSchedule.PreSelected = preSelectForOccurrence; checkInSchedule.ExcludedByFilter = excludeSchedule; person.PossibleSchedules.Add(checkInSchedule); } } } } }
public HttpResponseMessage Family(string param) { try { var session = HttpContext.Current.Session; var localDeviceConfigCookie = HttpContext.Current.Request.Cookies[CheckInCookieKey.LocalDeviceConfig].Value; var localDevice = localDeviceConfigCookie.FromJsonOrNull <LocalDeviceConfiguration>(); var currentKioskId = localDevice.CurrentKioskId.Value; Guid blockGuid = ( Guid )session["BlockGuid"]; var currentCheckInState = new CheckInState(currentKioskId, localDevice.CurrentCheckinTypeId, localDevice.CurrentGroupTypeIds); currentCheckInState.CheckIn.UserEnteredSearch = true; currentCheckInState.CheckIn.ConfirmSingleFamily = true; currentCheckInState.CheckIn.SearchType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CHECKIN_SEARCH_TYPE_PHONE_NUMBER); currentCheckInState.CheckIn.SearchValue = param; var rockContext = new Rock.Data.RockContext(); var block = BlockCache.Get(blockGuid); string workflowActivity = block.GetAttributeValue("WorkflowActivity"); Guid? workflowGuid = block.GetAttributeValue("WorkflowType").AsGuidOrNull(); List <string> errors; var workflowService = new WorkflowService(rockContext); var workflowType = WorkflowTypeCache.Get(workflowGuid.Value); var CurrentWorkflow = Rock.Model.Workflow.Activate(workflowType, currentCheckInState.Kiosk.Device.Name, rockContext); var activityType = workflowType.ActivityTypes.Where(a => a.Name == workflowActivity).FirstOrDefault(); if (activityType != null) { WorkflowActivity.Activate(activityType, CurrentWorkflow, rockContext); if (workflowService.Process(CurrentWorkflow, currentCheckInState, out errors)) { if (errors.Any()) { var innerException = new Exception(string.Join(" -- ", errors)); ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details.", innerException)); } // Keep workflow active for continued processing CurrentWorkflow.CompletedDateTime = null; SaveState(session, currentCheckInState); List <CheckInFamily> families = currentCheckInState.CheckIn.Families; families = families.OrderBy(f => f.Caption).ToList(); return(ControllerContext.Request.CreateResponse(HttpStatusCode.OK, families)); } else { if (errors.Any()) { var innerException = new Exception(string.Join(" -- ", errors)); ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details.", innerException)); } else { ExceptionLogService.LogException(new Exception("Process Mobile Checkin failed initial workflow. See inner exception for details.")); } } } else { return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, string.Format("Workflow type does not have a '{0}' activity type", workflowActivity))); } return(ControllerContext.Request.CreateResponse(HttpStatusCode.InternalServerError, String.Join("\n", errors))); } catch (Exception ex) { ExceptionLogService.LogException(ex, HttpContext.Current); return(ControllerContext.Request.CreateResponse(HttpStatusCode.Forbidden, "Forbidden")); } }