/// <summary> /// Gets the occurrence items. /// </summary> private AttendanceOccurrence GetOccurrence(RockContext rockContext, Group group, DateTime date, bool allowAdd) { var occurrenceService = new AttendanceOccurrenceService(rockContext); var occurrence = occurrenceService.Get(date.Date, group.Id, null, group.ScheduleId); // If an occurrence date was included, but no occurrence was found with that date, and new // occurrences can be added, create a new one if (occurrence == null && allowAdd) { // Create a new occurrence record and return it occurrence = new AttendanceOccurrence { Group = group, GroupId = group.Id, OccurrenceDate = date.Date, LocationId = null, ScheduleId = group.ScheduleId, }; occurrenceService.Add(occurrence); return(occurrence); } return(occurrence); }
public void AttendanceOccurrenceDateKeyJoinsCorrectly() { var expectedRecordCount = 15; var year = 2016; using (var rockContext = new RockContext()) { var minDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, year); var maxDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, year); var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext); var dates = new List <DateTime>(); DateTime GetUniqueDate() { var date = TestDataHelper.GetRandomDateInRange(minDateValue, maxDateValue); while (dates.Contains(date)) { date = TestDataHelper.GetRandomDateInRange(minDateValue, maxDateValue); } dates.Add(date); return(date); } for (var i = 0; i < 15; i++) { var attendanceOccurrence = BuildAttendanceOccurrence(rockContext, GetUniqueDate()); attendanceOccurrenceService.Add(attendanceOccurrence); } rockContext.SaveChanges(); } using (var rockContext = new RockContext()) { var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext); var attendanceOccurrences = attendanceOccurrenceService. Queryable(). Where(i => i.ForeignKey == attendanceOccurrenceForeignKey). Where(i => i.OccurrenceSourceDate.CalendarYear == year); Assert.AreEqual(expectedRecordCount, attendanceOccurrences.Count()); var actualAttendanceOccurrences = attendanceOccurrences.First(); var actualOccurrenceSourceDate = actualAttendanceOccurrences.OccurrenceSourceDate; Assert.IsNotNull(actualOccurrenceSourceDate); } }
public void AttendanceOccurrenceDateKeySavesCorrectly() { var rockContext = new RockContext(); var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext); var attendanceOccurrence = BuildAttendanceOccurrence(rockContext, Convert.ToDateTime("3/15/2010")); attendanceOccurrenceService.Add(attendanceOccurrence); rockContext.SaveChanges(); var attendanceOccurrenceId = attendanceOccurrence.Id; // We're bypassing the model because the model doesn't user the AttendanceOccurrenceDateKey from the database, // but it still needs to be correct for inner joins to work correctly. var result = rockContext.Database. SqlQuery <int>($"SELECT OccurrenceDateKey FROM AttendanceOccurrence WHERE Id = {attendanceOccurrenceId}").First(); Assert.AreEqual(20100315, result); }
private static AttendanceOccurrence GetOrAddOccurrence(RockContext rockContext, Group group, Event ebEvent) { var occurrenceService = new AttendanceOccurrenceService(rockContext); // Get all the occurrences for this group for the selected dates, location and schedule var occurrences = occurrenceService.GetGroupOccurrences(group, ebEvent.Start.Local.Date, null, new List <int>(), new List <int>()).ToList(); var occ = occurrences.FirstOrDefault(o => o.OccurrenceDate.Date.Equals(ebEvent.Start.Local.Date)); if (occ == null) { occ = new AttendanceOccurrence { GroupId = group.Id, OccurrenceDate = ebEvent.Start.Local.Date }; occurrenceService.Add(occ); } return(occ); }
/// <summary> /// Creates an AttendanceOccurrence if one doesn't already exist and returns the ID. /// </summary> /// <param name="e">The RowEventArgs of the selected grid row.</param> /// <returns>The ID of an AttendanceOccurrence</returns> private int GetOccurrenceId(RowEventArgs e) { int occurrenceId = e.RowKeyId; if (occurrenceId == 0) { // Find or create occurrence. using (var rockContext = new RockContext()) { HiddenField hfOccurrenceDate = e.Row.FindControl("hfOccurrenceDate") as HiddenField; HiddenField hfGroupId = e.Row.FindControl("hfGroupId") as HiddenField; HiddenField hfScheduleId = e.Row.FindControl("hfScheduleId") as HiddenField; HiddenField hfLocationId = e.Row.FindControl("hfLocationId") as HiddenField; DateTime occurrenceDate = DateTime.Parse(hfOccurrenceDate.Value); int?groupId = hfGroupId.Value.AsIntegerOrNull(); int?scheduleId = hfScheduleId.Value.AsIntegerOrNull(); int?locationId = hfLocationId.Value.AsIntegerOrNull(); var group = new GroupService(rockContext).Get(groupId.Value); var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext); //If this occurrence has already been created, just return the existing one. var existingOccurrenceQry = attendanceOccurrenceService.Queryable().Where(o => o.OccurrenceDate == occurrenceDate); if (groupId != null) { existingOccurrenceQry = existingOccurrenceQry.Where(o => o.GroupId == groupId); } if (scheduleId != null) { existingOccurrenceQry = existingOccurrenceQry.Where(o => o.ScheduleId == scheduleId); } if (locationId != null) { existingOccurrenceQry = existingOccurrenceQry.Where(o => o.LocationId == locationId); } var existingOccurrences = existingOccurrenceQry.ToList(); if (existingOccurrences.Any()) { occurrenceId = existingOccurrences.FirstOrDefault().Id; } else { //Create new occurrence. var attendanceOccurrence = new AttendanceOccurrence(); if (groupId != null) { attendanceOccurrence.GroupId = groupId; } if (scheduleId != null) { attendanceOccurrence.ScheduleId = scheduleId; } if (locationId != null) { attendanceOccurrence.LocationId = locationId; } attendanceOccurrence.OccurrenceDate = occurrenceDate; attendanceOccurrenceService.Add(attendanceOccurrence); rockContext.SaveChanges(); occurrenceId = attendanceOccurrence.Id; } } return(occurrenceId); } return(occurrenceId); }
/// <summary> /// Creates a new AttendanceOccurrence record. /// </summary> private bool CreateNewOccurrence() { using (var rockContext = new RockContext()) { int?groupId = PageParameter(PageParameterKey.GroupId).AsIntegerOrNull(); var group = new GroupService(rockContext).Get(groupId.Value); //Create new occurrence. var occurrence = new AttendanceOccurrence(); occurrence.Name = tbOccurrenceName.Text; occurrence.GroupId = groupId; if (locpLocation.Location != null) { occurrence.Location = new LocationService(rockContext).Get(locpLocation.Location.Id); occurrence.LocationId = occurrence.Location.Id; } else { occurrence.Location = null; occurrence.LocationId = null; } // The schedule is OK to be null occurrence.ScheduleId = spSchedule.SelectedValueAsId(); if (dpOccurrenceDate.SelectedDate.HasValue) { occurrence.OccurrenceDate = dpOccurrenceDate.SelectedDate.Value; } var occurrenceService = new AttendanceOccurrenceService(rockContext); // If this occurrence has already been created, just use the existing one. var existingOccurrences = occurrenceService.Queryable() .Where(o => o.GroupId == occurrence.GroupId) .Where(o => o.OccurrenceDate == occurrence.OccurrenceDate) .Where(o => o.ScheduleId == occurrence.ScheduleId) .Where(o => o.LocationId == occurrence.LocationId) .ToList(); if (existingOccurrences.Any()) { occurrence = existingOccurrences.FirstOrDefault(); } else { occurrenceService.Add(occurrence); } occurrence.DeclineConfirmationMessage = heDeclineMessage.Text; occurrence.AcceptConfirmationMessage = heAcceptMessage.Text; occurrence.ShowDeclineReasons = rcbShowDeclineReasons.Checked; var selectedDeclineReasons = new List <string>(); foreach (ListItem listItem in rcblAvailableDeclineReasons.Items) { if (listItem.Selected) { selectedDeclineReasons.Add(listItem.Value); } } occurrence.DeclineReasonValueIds = selectedDeclineReasons.AsDelimited(","); rockContext.SaveChanges(); occurrence = occurrenceService.Get(occurrence.Id); hfNewOccurrenceId.Value = occurrence.Id.ToString(); ShowDetails(rockContext, occurrence.Id, group); return(true); } }
/// <summary> /// Method to save attendance for use in two separate areas. /// </summary> protected bool SaveAttendance() { using (var rockContext = new RockContext()) { var occurrenceService = new AttendanceOccurrenceService(rockContext); var attendanceService = new AttendanceService(rockContext); var personAliasService = new PersonAliasService(rockContext); var locationService = new LocationService(rockContext); AttendanceOccurrence occurrence = null; if (_occurrence.Id != 0) { occurrence = occurrenceService.Get(_occurrence.Id); } if (occurrence == null) { var existingOccurrence = occurrenceService.Get(_occurrence.OccurrenceDate, _group.Id, _occurrence.LocationId, _occurrence.ScheduleId); if (existingOccurrence != null) { nbNotice.Heading = "Occurrence Already Exists"; nbNotice.Text = "<p>An occurrence already exists for this group for the selected date, location, and schedule that you've selected. Please return to the list and select that occurrence to update it's attendance.</p>"; nbNotice.NotificationBoxType = NotificationBoxType.Danger; nbNotice.Visible = true; return(false); } else { occurrence = new AttendanceOccurrence(); occurrence.GroupId = _occurrence.GroupId; occurrence.LocationId = _occurrence.LocationId; occurrence.ScheduleId = _occurrence.ScheduleId; occurrence.OccurrenceDate = _occurrence.OccurrenceDate; occurrenceService.Add(occurrence); } } occurrence.Notes = GetAttributeValue("ShowNotes").AsBoolean() ? dtNotes.Text : string.Empty; occurrence.DidNotOccur = cbDidNotMeet.Checked; var existingAttendees = occurrence.Attendees.ToList(); // If did not meet was selected and this was a manually entered occurrence (not based on a schedule/location) // then just delete all the attendance records instead of tracking a 'did not meet' value if (cbDidNotMeet.Checked && !_occurrence.ScheduleId.HasValue) { foreach (var attendance in existingAttendees) { attendanceService.Delete(attendance); } } else { int?campusId = locationService.GetCampusIdForLocation(_occurrence.LocationId) ?? _group.CampusId; if (!campusId.HasValue && _allowCampusFilter) { var campus = CampusCache.Get(bddlCampus.SelectedValueAsInt() ?? 0); if (campus != null) { campusId = campus.Id; } } if (cbDidNotMeet.Checked) { // If the occurrence is based on a schedule, set the did not meet flags foreach (var attendance in existingAttendees) { attendance.DidAttend = null; } } else { foreach (var attendee in _attendees) { var attendance = existingAttendees .Where(a => a.PersonAlias.PersonId == attendee.PersonId) .FirstOrDefault(); if (attendance == null) { int?personAliasId = personAliasService.GetPrimaryAliasId(attendee.PersonId); if (personAliasId.HasValue) { attendance = new Attendance(); attendance.PersonAliasId = personAliasId; attendance.CampusId = campusId; attendance.StartDateTime = _occurrence.OccurrenceDate; // check that the attendance record is valid cvAttendance.IsValid = attendance.IsValid; if (!cvAttendance.IsValid) { cvAttendance.ErrorMessage = attendance.ValidationResults.Select(a => a.ErrorMessage).ToList().AsDelimited("<br />"); return(false); } occurrence.Attendees.Add(attendance); } } if (attendance != null) { attendance.DidAttend = attendee.Attended; } } } } rockContext.SaveChanges(); if (occurrence.LocationId.HasValue) { Rock.CheckIn.KioskLocationAttendance.Remove(occurrence.LocationId.Value); } Guid?workflowTypeGuid = GetAttributeValue("Workflow").AsGuidOrNull(); if (workflowTypeGuid.HasValue) { var workflowType = WorkflowTypeCache.Get(workflowTypeGuid.Value); if (workflowType != null && (workflowType.IsActive ?? true)) { try { var workflow = Workflow.Activate(workflowType, _group.Name); workflow.SetAttributeValue("StartDateTime", _occurrence.OccurrenceDate.ToString("o")); workflow.SetAttributeValue("Schedule", _group.Schedule.Guid.ToString()); List <string> workflowErrors; new WorkflowService(rockContext).Process(workflow, _group, out workflowErrors); } catch (Exception ex) { ExceptionLogService.LogException(ex, this.Context); } } } } return(true); }
/// <summary> /// Loads the attendance data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadAttendance(CSVInstance csvData) { var lookupContext = new RockContext(); var groupService = new GroupService(lookupContext); var locationService = new LocationService(lookupContext); var attendanceService = new AttendanceService(lookupContext); var currentGroup = new Group(); int?currentGroupId = null; var location = new Location(); int?locationId = null; int?campusId = null; var newAttendanceList = new List <Attendance>(); var newOccurrences = new List <AttendanceOccurrence>(); var existingOccurrences = new AttendanceOccurrenceService(lookupContext).Queryable().AsNoTracking() .Select(o => new { o.Id, o.GroupId, o.LocationId, o.ScheduleId, o.OccurrenceDate }).ToDictionary(k => $"{k.GroupId}|{k.LocationId}|{k.ScheduleId}|{k.OccurrenceDate}", v => v.Id); var archivedScheduleName = "Archived Attendance"; var archivedSchedule = new ScheduleService(lookupContext).Queryable() .FirstOrDefault(s => s.Name.Equals(archivedScheduleName)); if (archivedSchedule == null) { archivedSchedule = AddNamedSchedule(lookupContext, archivedScheduleName, null, null, null, ImportDateTime, archivedScheduleName.RemoveSpecialCharacters(), true, ImportPersonAliasId); } var completed = 0; var importedCount = 0; var alreadyImportedCount = attendanceService.Queryable().AsNoTracking().Count(a => a.ForeignKey != null); ReportProgress(0, string.Format("Starting attendance import ({0:N0} already exist).", alreadyImportedCount)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowAttendanceKey = row[AttendanceId]; var rowGroupKey = row[AttendanceGroupId]; var rowPersonKey = row[AttendancePersonId]; var rowDate = row[AttendanceDate]; var rowCreatedDate = row[AttendanceCreatedDate]; var rowAttended = row[AttendanceAttended]; var rowLocationKey = row[AttendanceLocationId]; var rowAttendanceId = rowAttendanceKey.AsType <int?>(); // // Find this person in the database. // var personKeys = GetPersonKeys(rowPersonKey); if (personKeys == null || personKeys.PersonId == 0) { ReportProgress(0, string.Format("Person key {0} not found", rowPersonKey)); } // // Check that this attendance record doesn't already exist. // var attendanceExists = false; if (ImportedGroups.Count > 0 && rowGroupKey != currentGroup?.ForeignKey) { currentGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey == rowGroupKey); currentGroupId = currentGroup?.Id; } // // If we have a valid matching location, set the location and campus. // if (!string.IsNullOrEmpty(rowLocationKey)) { location = locationService.Queryable().FirstOrDefault(l => l.ForeignKey == rowLocationKey); locationId = location.Id; campusId = location.CampusId; } if (alreadyImportedCount > 0) { attendanceExists = attendanceService.Queryable().AsNoTracking().Any(a => a.ForeignKey == rowAttendanceKey); } if (!attendanceExists && (personKeys != null && personKeys.PersonId != 0)) { // // Create and populate the new attendance record. // var attendance = new Attendance { PersonAliasId = personKeys.PersonAliasId, ForeignKey = rowAttendanceKey, ForeignId = rowAttendanceId, DidAttend = ParseBoolOrDefault(rowAttended, true), StartDateTime = ( DateTime )ParseDateOrDefault(rowDate, ImportDateTime), CreatedDateTime = ParseDateOrDefault(rowCreatedDate, ImportDateTime), ModifiedDateTime = ImportDateTime, CreatedByPersonAliasId = ImportPersonAliasId, ModifiedByPersonAliasId = ImportPersonAliasId, CampusId = campusId }; var startDateString = (( DateTime )ParseDateOrDefault(rowDate, ImportDateTime)).Date; // occurrence is required for attendance int?occurrenceId = existingOccurrences.GetValueOrNull($"{currentGroupId}|{locationId}|{archivedSchedule.Id}|{startDateString}"); if (occurrenceId.HasValue) { attendance.OccurrenceId = occurrenceId.Value; } else { var newOccurrence = AddOccurrence(null, ( DateTime )ParseDateOrDefault(rowDate, ImportDateTime), currentGroupId, archivedSchedule.Id, locationId, true); if (newOccurrence != null) { attendance.OccurrenceId = newOccurrence.Id; existingOccurrences.Add($"{currentGroupId}|{locationId}|{archivedSchedule.Id}|{startDateString}", newOccurrence.Id); } } // // Add the attendance record for delayed saving. // newAttendanceList.Add(attendance); importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} attendance records processed, {1:N0} imported.", completed, importedCount)); } if (completed % ReportingNumber < 1) { SaveAttendance(newAttendanceList); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables currentGroup = new Group(); newAttendanceList.Clear(); groupService = new GroupService(lookupContext); locationService = new LocationService(lookupContext); attendanceService = new AttendanceService(lookupContext); } } // // Save any final changes to new groups // if (newAttendanceList.Any()) { SaveAttendance(newAttendanceList); } // // Save any changes to existing groups // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, string.Format("Finished attendance import: {0:N0} records added.", importedCount)); return(completed); }
/// <summary> /// Maps the attendance data. /// </summary> /// <param name="tableData">The table data.</param> /// <param name="totalRows">The total rows.</param> private void MapAttendance(IQueryable <Row> tableData, long totalRows = 0) { var lookupContext = new RockContext(); var newAttendances = new List <Attendance>(); var importedAttendancesCount = lookupContext.Attendances.AsNoTracking() .Count(a => a.ForeignKey != null); var importedCodes = lookupContext.AttendanceCodes.AsNoTracking() .Where(c => c.ForeignKey != null).ToList(); var importedDevices = lookupContext.Devices.AsNoTracking() .Where(d => d.DeviceTypeValueId == DeviceTypeCheckinKioskId).ToList(); var newOccurrences = new List <AttendanceOccurrence>(); var existingOccurrences = new AttendanceOccurrenceService(lookupContext).Queryable().AsNoTracking() .Select(o => new { o.Id, o.GroupId, o.LocationId, o.ScheduleId, o.OccurrenceDate }).ToDictionary(k => $"{k.GroupId}|{k.LocationId}|{k.ScheduleId}|{k.OccurrenceDate}", v => v.Id); var archivedScheduleName = "Archived Attendance"; var archivedSchedule = new ScheduleService(lookupContext).Queryable() .FirstOrDefault(s => s.Name.Equals(archivedScheduleName)); if (archivedSchedule == null) { archivedSchedule = AddNamedSchedule(lookupContext, archivedScheduleName, null, null, null, ImportDateTime, archivedScheduleName.RemoveSpecialCharacters(), true, ImportPersonAliasId); } if (totalRows == 0) { totalRows = tableData.Count(); } var completedItems = 0; var percentage = (totalRows - 1) / 100 + 1; ReportProgress(0, $"Verifying attendance import ({importedAttendancesCount:N0} already exist)."); foreach (var row in tableData.Where(r => r != null)) { var rlcId = row["RLC_ID"] as int?; var individualId = row["Individual_ID"] as int?; var startDate = row["Start_Date_Time"] as DateTime?; var attendanceCode = row["Tag_Code"] as string; var attendanceNote = row["BreakoutGroup_Name"] as string; var checkinDate = row["Check_In_Time"] as DateTime?; var checkoutDate = row["Check_Out_Time"] as DateTime?; var machineName = row["Checkin_Machine_Name"] as string; var activityScheduleId = row["Activity_schedule_ID"] as int?; int?scheduleId = null; // at minimum, attendance needs a person and a date var personKeys = GetPersonKeys(individualId, null); if (personKeys != null && personKeys.PersonAliasId > 0 && startDate.HasValue) { // create the initial attendance var attendance = new Attendance { PersonAliasId = personKeys.PersonAliasId, DidAttend = true, Note = attendanceNote, StartDateTime = ( DateTime )startDate, EndDateTime = checkoutDate, CreatedDateTime = checkinDate, ForeignKey = $"Attendance imported {ImportDateTime}" }; // add the RLC info if it exists int?rockGroupId = null; int?locationId = null; var startDateString = (( DateTime )startDate).Date; if (rlcId.HasValue) { var rlcGroup = ImportedGroups.FirstOrDefault(g => g.ForeignId.Equals(rlcId)); rockGroupId = rlcGroup?.Id; locationId = rlcGroup?.GroupLocations.Select(gl => ( int? )gl.LocationId).FirstOrDefault(); attendance.CampusId = rlcGroup?.CampusId; scheduleId = rlcGroup?.ScheduleId; } else if (activityScheduleId.HasValue && activityScheduleId.Value > 0) { int?existingScheduleId = lookupContext.Schedules.AsNoTracking().AsQueryable().Where(s => s.ForeignId == activityScheduleId).Select(s => s.Id).FirstOrDefault(); if (existingScheduleId.HasValue && existingScheduleId.Value > 0) { scheduleId = existingScheduleId.Value; } } if (!scheduleId.HasValue) { scheduleId = archivedSchedule.Id; } // occurrence is required for attendance int?occurrenceId = existingOccurrences.GetValueOrNull($"{rockGroupId}|{locationId}|{scheduleId}|{startDateString}"); if (occurrenceId.HasValue) { attendance.OccurrenceId = occurrenceId.Value; } else { var newOccurrence = AddOccurrence(null, ( DateTime )startDate, rockGroupId, scheduleId, locationId, true); if (newOccurrence != null) { attendance.OccurrenceId = newOccurrence.Id; existingOccurrences.Add($"{rockGroupId}|{locationId}|{scheduleId}|{startDateString}", newOccurrence.Id); } } // add the tag code //if ( !string.IsNullOrWhiteSpace( attendanceCode ) ) //{ //var issueDatetime = checkinDate ?? (DateTime)startDate; //var code = importedCodes.FirstOrDefault( c => c.Code.Equals( attendanceCode ) && c.IssueDateTime.Equals( issueDatetime ) ); //if ( code == null ) //{ // code = new AttendanceCode // { // Code = attendanceCode, // IssueDateTime = issueDatetime, // ForeignKey = string.Format( "Attendance imported {0}", ImportDateTime ) // }; // lookupContext.AttendanceCodes.Add( code ); // lookupContext.SaveChanges(); // importedCodes.Add( code ); //} //attendance.AttendanceCodeId = code.Id; //} // add the device //if ( !string.IsNullOrWhiteSpace( machineName ) ) //{ // var device = importedDevices.FirstOrDefault( d => d.Name.Equals( machineName, StringComparison.OrdinalIgnoreCase ) ); // if ( device == null ) // { // device = AddDevice( lookupContext, machineName, null, DeviceTypeCheckinKioskId, null, null, ImportDateTime, // $"{machineName} imported {ImportDateTime}", true, ImportPersonAliasId ); // importedDevices.Add( device ); // } // attendance.DeviceId = device.Id; //} newAttendances.Add(attendance); completedItems++; if (completedItems % percentage < 1) { var percentComplete = completedItems / percentage; ReportProgress(percentComplete, $"{completedItems:N0} attendances imported ({percentComplete}% complete)."); } if (completedItems % ReportingNumber < 1) { SaveAttendances(newAttendances, false); ReportPartialProgress(); // Reset lists and context lookupContext.Dispose(); lookupContext = new RockContext(); newAttendances.Clear(); } } } if (newAttendances.Any()) { SaveAttendances(newAttendances, false); } lookupContext.Dispose(); ReportProgress(100, $"Finished attendance import: {completedItems:N0} attendances imported."); }
/// <summary> /// Maps the groups attendance data. /// </summary> /// <param name="tableData">The table data.</param> /// <param name="totalRows">The total rows.</param> private void MapGroupsAttendance(IQueryable <Row> tableData, long totalRows = 0) { var lookupContext = new RockContext(); var newAttendances = new List <Attendance>(); var importedAttendancesCount = lookupContext.Attendances.AsNoTracking() .Count(a => a.ForeignKey != null && a.Occurrence.GroupId.HasValue && a.Occurrence.Group.GroupTypeId == GeneralGroupTypeId); var archivedScheduleName = "Archived Attendance"; var archivedSchedule = new ScheduleService(lookupContext).Queryable() .FirstOrDefault(s => s.Name.Equals(archivedScheduleName)); if (archivedSchedule == null) { archivedSchedule = AddNamedSchedule(lookupContext, archivedScheduleName, null, null, null, ImportDateTime, archivedScheduleName.RemoveSpecialCharacters(), true, ImportPersonAliasId); } var existingOccurrences = new AttendanceOccurrenceService(lookupContext).Queryable().AsNoTracking() .Select(o => new { o.Id, o.GroupId, o.LocationId, o.ScheduleId, o.OccurrenceDate }).ToDictionary(k => $"{k.GroupId}|{k.LocationId}|{k.ScheduleId}|{k.OccurrenceDate}", v => v.Id); if (totalRows == 0) { totalRows = tableData.Count(); } var completedItems = 0; var percentage = (totalRows - 1) / 100 + 1; ReportProgress(0, $"Verifying group attendance import, ({totalRows:N0} found, {importedAttendancesCount:N0} already exist)."); foreach (var row in tableData.Where(r => r != null)) { var groupId = row["GroupID"] as int?; var startDate = row["StartDateTime"] as DateTime?; var endDate = row["EndDateTime"] as DateTime?; var attendanceNote = row["Comments"] as string; var wasPresent = row["Individual_Present"] as int?; var individualId = row["IndividualID"] as int?; var checkinDate = row["CheckinDateTime"] as DateTime?; var checkoutDate = row["CheckoutDateTime"] as DateTime?; var createdDate = row["AttendanceCreatedDate"] as DateTime?; var scheduleForeignKey = "F1GD_" + groupId.Value.ToString(); int?scheduleId = null; var personKeys = GetPersonKeys(individualId, null); if (personKeys != null && personKeys.PersonAliasId > 0 && startDate.HasValue) { // create the initial attendance var attendance = new Attendance { PersonAliasId = personKeys.PersonAliasId, DidAttend = wasPresent != 0, Note = attendanceNote, StartDateTime = ( DateTime )startDate, EndDateTime = checkoutDate, CreatedDateTime = checkinDate, ForeignKey = $"Group Attendance imported {ImportDateTime}" }; // add the group info if it exists int?rockGroupId = null; int?locationId = null; var startDateString = (( DateTime )startDate).Date; if (groupId.HasValue) { var peopleGroup = ImportedGroups.FirstOrDefault(g => g.ForeignId.Equals(groupId)); rockGroupId = peopleGroup?.Id; locationId = peopleGroup?.GroupLocations.Select(gl => ( int? )gl.LocationId).FirstOrDefault(); attendance.CampusId = peopleGroup?.CampusId; scheduleId = peopleGroup?.ScheduleId; } else if (lookupContext.Schedules.AsNoTracking().AsQueryable().Any(s => s.ForeignKey == scheduleForeignKey)) { scheduleId = lookupContext.Schedules.AsNoTracking().AsQueryable().FirstOrDefault(s => s.ForeignKey == scheduleForeignKey).Id; } if (!scheduleId.HasValue || scheduleId.Value == 0) { scheduleId = archivedSchedule.Id; } // occurrence is required for attendance int?occurrenceId = existingOccurrences.GetValueOrNull($"{rockGroupId}|{locationId}|{scheduleId}|{startDateString}"); if (occurrenceId.HasValue) { attendance.OccurrenceId = occurrenceId.Value; } else { var newOccurrence = AddOccurrence(null, ( DateTime )startDate, rockGroupId, scheduleId, locationId, true); if (newOccurrence != null) { attendance.OccurrenceId = newOccurrence.Id; existingOccurrences.Add($"{rockGroupId}|{locationId}|{scheduleId}|{startDateString}", newOccurrence.Id); } } newAttendances.Add(attendance); completedItems++; if (completedItems % percentage < 1) { var percentComplete = completedItems / percentage; ReportProgress(percentComplete, $"{completedItems:N0} group attendances imported ({percentComplete}% complete)."); } if (completedItems % ReportingNumber < 1) { SaveAttendances(newAttendances); ReportPartialProgress(); // Reset lists and context lookupContext.Dispose(); lookupContext = new RockContext(); newAttendances.Clear(); } } } if (newAttendances.Any()) { SaveAttendances(newAttendances); } lookupContext.Dispose(); ReportProgress(100, $"Finished group attendance import: {completedItems:N0} attendances imported."); }
/// <summary> /// Handles the Click event of the lbSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void lbSave_Click(object sender, EventArgs e) { if (CurrentGroup != null) { if (ddlOccurence.SelectedValue.AsInteger() != 0) { //The drop down stores the time in unix time var occurenceDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local) .AddSeconds(ddlOccurence.SelectedValue.AsInteger()); var attendanceData = new AttendanceService(_rockContext) .Queryable("PersonAlias") .Where(a => a.Occurrence.GroupId == CurrentGroup.Id && a.StartDateTime == occurenceDate); var attendanceOccurenceService = new AttendanceOccurrenceService(_rockContext); if (cbDidNotMeet.Checked == true) { var occurrence = attendanceOccurenceService.Get(occurenceDate.Date, CurrentGroup.Id, null, CurrentGroup.ScheduleId); if (occurrence == null) { occurrence = new AttendanceOccurrence(); occurrence.OccurrenceDate = occurenceDate; occurrence.GroupId = CurrentGroup.Id; occurrence.ScheduleId = CurrentGroup.ScheduleId; attendanceOccurenceService.Add(occurrence); } occurrence.DidNotOccur = true; foreach (var attendee in occurrence.Attendees) { attendee.DidAttend = false; } } else { var attendanceService = new AttendanceService(_rockContext); var personAliasService = new PersonAliasService(_rockContext); foreach (var item in lvMembers.Items) { var hfMember = item.FindControl("hfMember") as HiddenField; var cbMember = item.FindControl("cbMember") as HtmlInputCheckBox; var personId = hfMember.Value.AsInteger(); var attendanceItem = attendanceData.Where(a => a.PersonAlias.PersonId == personId) .FirstOrDefault(); if (attendanceItem == null) { var attendancePerson = new PersonService(_rockContext).Get(personId); if (attendancePerson != null && attendancePerson.PrimaryAliasId.HasValue) { attendanceItem = attendanceService.AddOrUpdate(attendancePerson.PrimaryAliasId.Value, occurenceDate, CurrentGroup.Id, null, CurrentGroup.ScheduleId, CurrentGroup.CampusId); } } if (attendanceItem != null) { attendanceItem.DidAttend = cbMember.Checked; } } } } _rockContext.SaveChanges(); nbNotice.Text = "Attendance Saved"; nbNotice.NotificationBoxType = NotificationBoxType.Success; nbNotice.Visible = true; nbNotice.Dismissable = true; } }