/// <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, WorkflowAction action, Object entity, out List <string> errorMessages) { var checkInState = GetCheckInState(entity, out errorMessages); if (checkInState != null) { var people = checkInState.CheckIn.CurrentFamily.People .Where(p => p.Selected) .Select(p => p.Person) .ToList(); var checkInLabels = CheckinLabelGen.GenerateLabels(people, checkInState.Kiosk.Device, GetAttributeValue(action, "AggregatedLabel").AsGuidOrNull()); var groupType = checkInState.CheckIn.CurrentFamily.People .Where(p => p.Selected) .SelectMany(p => p.GroupTypes.Where(gt => gt.Selected)) .FirstOrDefault(); if (groupType != null) { groupType.Labels = checkInLabels; } //For mobile check-in we need to serialize this data and save it in the database. //This will mean that when it's time to finish checkin in //All we will need to do is deserialize and pass the data to the printer if (GetAttributeValue(action, "IsMobile").AsBoolean()) { MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); MobileCheckinRecord mobileCheckinRecord = mobileCheckinRecordService.Queryable() .Where(r => r.Status == MobileCheckinStatus.Active) .Where(r => r.CreatedDateTime > Rock.RockDateTime.Today) .Where(r => r.UserName == checkInState.CheckIn.SearchValue) .FirstOrDefault(); if (mobileCheckinRecord == null) { ExceptionLogService.LogException("Mobile Check-in failed to find mobile checkin record"); } mobileCheckinRecord.SerializedCheckInState = JsonConvert.SerializeObject(checkInLabels); rockContext.SaveChanges(); //Freshen cache (we're going to need it soon) MobileCheckinRecordCache.Update(mobileCheckinRecord.Id); } return(true); } errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null."); return(false); }
private void BindRepeater() { var campus = KioskType.Campus; if (campus == null) { nbError.Text = "Kiosk Type is not configured with a campus."; nbError.Visible = true; return; } RockContext rockContext = new RockContext(); MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); GroupService groupService = new GroupService(rockContext); var groupQry = groupService.Queryable(); var records = mobileCheckinRecordService.Queryable().AsNoTracking() .Where(r => r.CampusId == campus.Id && r.Status == MobileCheckinStatus.Active && r.CreatedDateTime >= Rock.RockDateTime.Today) .Join(groupQry, r => r.FamilyGroupId, g => g.Id, (r, g) => new { Record = r, Caption = g.Name, Attendances = r.Attendances.Where(a => a.EndDateTime == null) }) .ToList() .Select(r => new MCRPoco { Record = r.Record, Caption = r.Caption, SubCaption = string.Join("<br>", r.Attendances.Select(a => string.Format("{0}: {1} in {2} at {3}", a.PersonAlias.Person.NickName, a.Occurrence.Group.Name, a.Occurrence.Location.Name, a.Occurrence.Schedule.Name))) }) .OrderBy(r => r.Caption) .ToList(); rMCR.DataSource = records; rMCR.DataBind(); pnlNoRecords.Visible = !records.Any(); }
private void MobileCheckin(string accessKey) { var mobileDidAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_DID_ATTEND).Id; var mobileNotAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_NOT_ATTEND).Id; RockContext rockContext = new RockContext(); MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); var mobileCheckinRecord = mobileCheckinRecordService.Queryable().Where(r => r.AccessKey == accessKey).FirstOrDefault(); if (mobileCheckinRecord == null) { mdAlert.Show("Mobile check-in record not found", ModalAlertType.Alert); BindRepeater(); return; } else if (mobileCheckinRecord.Status == MobileCheckinStatus.Canceled) { mdAlert.Show("Mobile check-in record is expired.", ModalAlertType.Alert); BindRepeater(); return; } else if (mobileCheckinRecord.Status == MobileCheckinStatus.Complete) { mdAlert.Show("Mobile check-in record has already been completed.", ModalAlertType.Alert); BindRepeater(); return; } try { if (mobileCheckinRecord == null) { return; } List <CheckInLabel> labels = null; if (mobileCheckinRecord.Attendances.Any(a => a.EndDateTime != null)) { var people = mobileCheckinRecord.Attendances.Select(a => a.PersonAlias.Person).DistinctBy(p => p.Id).ToList(); labels = CheckinLabelGen.GenerateLabels(people, CurrentCheckInState.Kiosk.Device, GetAttributeValue("AggregatedLabel").AsGuidOrNull()); } else { labels = JsonConvert.DeserializeObject <List <CheckInLabel> >(mobileCheckinRecord.SerializedCheckInState); } LabelPrinter labelPrinter = new LabelPrinter() { Request = Request, Labels = labels }; labelPrinter.PrintNetworkLabels(); var script = labelPrinter.GetClientScript(); ScriptManager.RegisterStartupScript(upContent, upContent.GetType(), "addLabelScript", script, true); foreach (var attendance in mobileCheckinRecord.Attendances) { if (attendance.QualifierValueId == mobileDidAttendId) { attendance.DidAttend = true; attendance.QualifierValueId = null; attendance.StartDateTime = Rock.RockDateTime.Now; } else if (attendance.QualifierValueId == mobileNotAttendId) { attendance.DidAttend = false; attendance.QualifierValueId = null; } attendance.Note = "Completed mobile check-in at: " + CurrentCheckInState.Kiosk.Device.Name; } mobileCheckinRecord.Status = MobileCheckinStatus.Complete; rockContext.SaveChanges(); //wait until we successfully save to update cache foreach (var attendance in mobileCheckinRecord.Attendances) { AttendanceCache.AddOrUpdate(attendance); } MobileCheckinRecordCache.Update(mobileCheckinRecord.Id); BindRepeater(); } catch (Exception e) { LogException(e); mdAlert.Show("An unexpected issue occurred.", ModalAlertType.Alert); BindRepeater(); } }
private void MobileCheckin(string accessKey) { var mobileDidAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_DID_ATTEND).Id; var mobileNotAttendId = DefinedValueCache.Get(Constants.DEFINED_VALUE_MOBILE_NOT_ATTEND).Id; RockContext rockContext = new RockContext(); MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); var mobileCheckinRecord = mobileCheckinRecordService.Queryable().Where(r => r.AccessKey == accessKey).FirstOrDefault(); if (mobileCheckinRecord == null) { MobileCheckinMessage(GetAttributeValue(AttributeKeys.NoMobileCheckinRecord)); return; } else if (mobileCheckinRecord.Status == MobileCheckinStatus.Canceled) { MobileCheckinMessage(GetAttributeValue(AttributeKeys.ExpiredMobileCheckinRecord)); return; } else if (mobileCheckinRecord.Status == MobileCheckinStatus.Complete) { MobileCheckinMessage(GetAttributeValue(AttributeKeys.AlreadyCompleteCheckinRecord)); return; } try { if (mobileCheckinRecord == null) { return; } if (KioskType.CampusId.HasValue && KioskType.CampusId != 0 && KioskType.CampusId != mobileCheckinRecord.CampusId) { ShowWrongCampusSign(mobileCheckinRecord.Campus.Name, KioskType.Campus.Name); return; } List <CheckInLabel> labels = JsonConvert.DeserializeObject <List <CheckInLabel> >(mobileCheckinRecord.SerializedCheckInState); LabelPrinter labelPrinter = new LabelPrinter() { Request = Request, Labels = labels }; labelPrinter.PrintNetworkLabels(); var script = labelPrinter.GetClientScript(); ScriptManager.RegisterStartupScript(upContent, upContent.GetType(), "addLabelScript", script, true); foreach (var attendance in mobileCheckinRecord.Attendances) { if (attendance.QualifierValueId == mobileDidAttendId) { attendance.DidAttend = true; attendance.QualifierValueId = null; attendance.StartDateTime = Rock.RockDateTime.Now; } else if (attendance.QualifierValueId == mobileNotAttendId) { attendance.DidAttend = false; attendance.QualifierValueId = null; } attendance.Note = "Completed mobile check-in at: " + CurrentCheckInState.Kiosk.Device.Name; } mobileCheckinRecord.Status = MobileCheckinStatus.Complete; rockContext.SaveChanges(); //wait until we successfully save to update cache foreach (var attendance in mobileCheckinRecord.Attendances) { AttendanceCache.AddOrUpdate(attendance); } MobileCheckinRecordCache.Update(mobileCheckinRecord.Id); MobileCheckinMessage(GetAttributeValue(AttributeKeys.CompletingMobileCheckin), 5); } catch (Exception e) { } }
public static void Verify(ref List <string> errors) { RockContext rockContext = new RockContext(); MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); var mobileCheckinRecords = mobileCheckinRecordService.Queryable().Where(r => r.CreatedDateTime >= Rock.RockDateTime.Today).ToList(); var mcrCaches = All(); if (mobileCheckinRecords.Count != mcrCaches.Count) { var recordIds = mobileCheckinRecords.Select(r => r.Id); var cacheIds = mcrCaches.Select(r => r.Id); var missingCacheIds = recordIds.Except(cacheIds).ToList(); var extraCacheIds = cacheIds.Except(recordIds).ToList(); foreach (var id in missingCacheIds) { errors.Add($"Warning: Mobile Check-in Record Cache missing from All(): {id}"); } foreach (var id in extraCacheIds) { errors.Add($"Error: Extraneous Mobile Check-in Record Cache: {id}"); } } foreach (var mobileCheckinRecord in mobileCheckinRecords) { var mcrCache = Get(mobileCheckinRecord.Id); if (mcrCache == null) { errors.Add("Error: Mobile Checkin Record Cache missing for Mobile Checkin Record Id: " + mobileCheckinRecord.Id.ToString()); continue; } if (mobileCheckinRecord.FamilyGroupId != mcrCache.FamilyGroupId) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: FamilyGroupId - DB:{mobileCheckinRecord.FamilyGroupId} - Cache:{mcrCache.FamilyGroupId}"); } if (mobileCheckinRecord.UserName != mcrCache.UserName) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: UserName - DB:{mobileCheckinRecord.UserName} - Cache:{mcrCache.UserName}"); } if (mobileCheckinRecord.Attendances.Count != mcrCache.AttendanceIds.Count) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: Attendance Count - DB:{mobileCheckinRecord.Attendances.Count} - Cache:{mcrCache.AttendanceIds.Count}"); } if (mobileCheckinRecord.AccessKey != mcrCache.AccessKey) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: AccessKey - DB:{mobileCheckinRecord.AccessKey} - Cache:{mcrCache.AccessKey}"); } if (mobileCheckinRecord.CampusId != mcrCache.CampusId) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: CampusId - DB:{mobileCheckinRecord.CampusId} - Cache:{mcrCache.CampusId}"); } if (mobileCheckinRecord.ReservedUntilDateTime != mcrCache.ReservedUntilDateTime) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: ReservedUntilDateTime - DB:{mobileCheckinRecord.ReservedUntilDateTime} - Cache:{mcrCache.ReservedUntilDateTime}"); } if (mobileCheckinRecord.ExpirationDateTime != mcrCache.ExpirationDateTime) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: ExpirationDateTime - DB:{mobileCheckinRecord.ExpirationDateTime} - Cache:{mcrCache.ExpirationDateTime}"); } if (mobileCheckinRecord.SerializedCheckInState != mcrCache.SerializedCheckInState) { errors.Add($"Error: Mobile Checkin Record Cache (Id:{mobileCheckinRecord.Id}) Desync: SerializedCheckInState - DB:{mobileCheckinRecord.SerializedCheckInState} - Cache:{mcrCache.SerializedCheckInState}"); } if (mcrCache.SerializedCheckInState.IsNullOrWhiteSpace()) { errors.Add($"Info: Mobile Checkin Record Cache missing serialized check-in data. Id: {mobileCheckinRecord.Id}."); } //Todo Check Attendance Status } }
/// <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, WorkflowAction action, Object entity, out List <string> errorMessages) { var checkInState = GetCheckInState(entity, out errorMessages); CheckInGroupType lastCheckinGroupType = null; List <string> labelCodes = new List <string>(); List <int> childGroupIds; List <CheckInLabel> checkInLabels = new List <CheckInLabel>(); var volAttributeGuid = GetAttributeValue(action, "VolunteerGroupAttribute"); string volAttributeKey = ""; if (!string.IsNullOrWhiteSpace(volAttributeGuid)) { volAttributeKey = AttributeCache.Get(volAttributeGuid.AsGuid()).Key; childGroupIds = checkInState.Kiosk.KioskGroupTypes .SelectMany(g => g.KioskGroups) .Where(g => !g.Group.GetAttributeValue(volAttributeKey).AsBoolean()) .Select(g => g.Group.Id).ToList(); } else { childGroupIds = new List <int>(); } if (checkInState != null) { var attendanceService = new AttendanceService(rockContext); var globalAttributes = Rock.Web.Cache.GlobalAttributesCache.Get(); var globalMergeValues = Rock.Lava.LavaHelper.GetCommonMergeFields(null); var groupMemberService = new GroupMemberService(rockContext); foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected)) { foreach (var person in family.People.Where(p => p.Selected)) { if (person.GroupTypes.Where(gt => gt.Selected).SelectMany(gt => gt.Groups).Where(g => g.Selected && childGroupIds.Contains(g.Group.Id)).Any()) { labelCodes.Add((person.SecurityCode) + "-" + LabelAge(person.Person)); } if (string.IsNullOrEmpty(person.SecurityCode)) { var lastAttendance = attendanceService.Queryable() .Where(a => a.PersonAlias.PersonId == person.Person.Id && a.AttendanceCode != null) .OrderByDescending(a => a.StartDateTime) .FirstOrDefault(); if (lastAttendance != null) { person.SecurityCode = lastAttendance.AttendanceCode.Code; } } var firstCheckinGroupType = person.GroupTypes.Where(g => g.Selected).FirstOrDefault(); if (firstCheckinGroupType != null) { List <Guid> labelGuids = new List <Guid>(); var mergeObjects = new Dictionary <string, object>(); foreach (var keyValue in globalMergeValues) { mergeObjects.Add(keyValue.Key, keyValue.Value); } mergeObjects.Add("Person", person); mergeObjects.Add("GroupTypes", person.GroupTypes.Where(g => g.Selected).ToList()); List <Group> mergeGroups = new List <Group>(); List <Location> mergeLocations = new List <Location>(); List <Schedule> mergeSchedules = new List <Schedule>(); var sets = attendanceService .Queryable().AsNoTracking().Where(a => a.PersonAlias.Person.Id == person.Person.Id && a.StartDateTime >= Rock.RockDateTime.Today && a.EndDateTime == null && a.Occurrence.Group != null && a.Occurrence.Schedule != null && a.Occurrence.Location != null ) .Select(a => new { Group = a.Occurrence.Group, Location = a.Occurrence.Location, Schedule = a.Occurrence.Schedule, AttendanceGuid = a.Guid } ) .ToList() .OrderBy(a => a.Schedule.StartTimeOfDay); //Load breakout group var breakoutGroups = GetBreakoutGroups(person.Person, rockContext, action); //Add in an empty object as a placeholder for our breakout group mergeObjects.Add("BreakoutGroup", ""); //Add in GUID for QR code if (sets.Any()) { mergeObjects.Add("AttendanceGuid", sets.FirstOrDefault().AttendanceGuid.ToString()); } foreach (var set in sets) { mergeGroups.Add(set.Group); mergeLocations.Add(set.Location); mergeSchedules.Add(set.Schedule); //Add the breakout group mergefield if (breakoutGroups.Any()) { var breakoutGroup = breakoutGroups.Where(g => g.ScheduleId == set.Schedule.Id).FirstOrDefault(); if (breakoutGroup != null) { var breakoutGroupEntity = new GroupService(rockContext).Get(breakoutGroup.Id); if (breakoutGroupEntity != null) { breakoutGroupEntity.LoadAttributes(); var letter = breakoutGroupEntity.GetAttributeValue("Letter"); if (!string.IsNullOrWhiteSpace(letter)) { mergeObjects["BreakoutGroup"] = letter; } } } } } mergeObjects.Add("Groups", mergeGroups); mergeObjects.Add("Locations", mergeLocations); mergeObjects.Add("Schedules", mergeSchedules); foreach (var groupType in person.GroupTypes.Where(g => g.Selected)) { lastCheckinGroupType = groupType; groupType.Labels = new List <CheckInLabel>(); GetGroupTypeLabels(groupType.GroupType, firstCheckinGroupType.Labels, mergeObjects, labelGuids); var PrinterIPs = new Dictionary <int, string>(); foreach (var label in groupType.Labels) { label.PrintFrom = checkInState.Kiosk.Device.PrintFrom; label.PrintTo = checkInState.Kiosk.Device.PrintToOverride; if (label.PrintTo == PrintTo.Default) { label.PrintTo = groupType.GroupType.AttendancePrintTo; } if (label.PrintTo == PrintTo.Kiosk) { var device = checkInState.Kiosk.Device; if (device != null) { label.PrinterDeviceId = device.PrinterDeviceId; } } else if (label.PrintTo == PrintTo.Location) { // Should only be one var group = groupType.Groups.Where(g => g.Selected).FirstOrDefault(); if (group != null) { var location = group.Locations.Where(l => l.Selected).FirstOrDefault(); if (location != null) { var device = location.Location.PrinterDevice; if (device != null) { label.PrinterDeviceId = device.PrinterDeviceId; } } } } if (label.PrinterDeviceId.HasValue) { if (PrinterIPs.ContainsKey(label.PrinterDeviceId.Value)) { label.PrinterAddress = PrinterIPs[label.PrinterDeviceId.Value]; } else { var printerDevice = new DeviceService(rockContext).Get(label.PrinterDeviceId.Value); if (printerDevice != null) { PrinterIPs.Add(printerDevice.Id, printerDevice.IPAddress); label.PrinterAddress = printerDevice.IPAddress; } } } checkInLabels.Add(label); } } } } //Add in custom labels for parents //This is the aggregate part List <CheckInLabel> customLabels = new List <CheckInLabel>(); List <string> mergeCodes = (( string )GetAttributeValue(action, "MergeText")).Split(',').ToList(); while (labelCodes.Count > 0) { var mergeDict = new Dictionary <string, string>(); foreach (var mergeCode in mergeCodes) { if (labelCodes.Count > 0) { mergeDict.Add(mergeCode, labelCodes[0]); labelCodes.RemoveAt(0); } else { mergeDict.Add(mergeCode, ""); } } mergeDict.Add("Date", Rock.RockDateTime.Today.DayOfWeek.ToString().Substring(0, 3) + " " + Rock.RockDateTime.Today.ToMonthDayString()); var labelCache = KioskLabel.Get(new Guid(GetAttributeValue(action, "AggregatedLabel"))); if (labelCache != null) { var checkInLabel = new CheckInLabel(labelCache, new Dictionary <string, object>()); checkInLabel.FileGuid = new Guid(GetAttributeValue(action, "AggregatedLabel")); foreach (var keyValue in mergeDict) { if (checkInLabel.MergeFields.ContainsKey(keyValue.Key)) { checkInLabel.MergeFields[keyValue.Key] = keyValue.Value; } else { checkInLabel.MergeFields.Add(keyValue.Key, keyValue.Value); } } checkInLabel.PrintFrom = checkInState.Kiosk.Device.PrintFrom; checkInLabel.PrintTo = checkInState.Kiosk.Device.PrintToOverride; if (checkInLabel.PrintTo == PrintTo.Default) { checkInLabel.PrintTo = lastCheckinGroupType.GroupType.AttendancePrintTo; } if (checkInLabel.PrintTo == PrintTo.Kiosk) { var device = checkInState.Kiosk.Device; if (device != null) { checkInLabel.PrinterDeviceId = device.PrinterDeviceId; } } else if (checkInLabel.PrintTo == PrintTo.Location) { // Should only be one var group = lastCheckinGroupType.Groups.Where(g => g.Selected).FirstOrDefault(); if (group != null) { var location = group.Locations.Where(l => l.Selected).FirstOrDefault(); if (location != null) { var device = location.Location.PrinterDevice; if (device != null) { checkInLabel.PrinterDeviceId = device.PrinterDeviceId; } } } } if (checkInLabel.PrinterDeviceId.HasValue) { var printerDevice = new DeviceService(rockContext).Get(checkInLabel.PrinterDeviceId.Value); checkInLabel.PrinterAddress = printerDevice.IPAddress; } if (lastCheckinGroupType != null) { lastCheckinGroupType.Labels.Add(checkInLabel); checkInLabels.Add(checkInLabel); } } } } //For mobile check-in we need to serialize this data and save it in the database. //This will mean that when it's time to finish checkin in //All we will need to do is deserialize and pass the data to the printer if (GetAttributeValue(action, "IsMobile").AsBoolean()) { MobileCheckinRecordService mobileCheckinRecordService = new MobileCheckinRecordService(rockContext); MobileCheckinRecord mobileCheckinRecord = mobileCheckinRecordService.Queryable() .Where(r => r.Status == MobileCheckinStatus.Active) .Where(r => r.CreatedDateTime > Rock.RockDateTime.Today) .Where(r => r.UserName == checkInState.CheckIn.SearchValue) .FirstOrDefault(); if (mobileCheckinRecord == null) { ExceptionLogService.LogException("Mobile Check-in failed to find mobile checkin record"); } mobileCheckinRecord.SerializedCheckInState = JsonConvert.SerializeObject(checkInLabels); rockContext.SaveChanges(); //Freshen cache (we're going to need it soon) MobileCheckinRecordCache.Update(mobileCheckinRecord.Id); } return(true); } errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null."); return(false); }