/// <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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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.");
        }
Beispiel #10
0
        /// <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;
            }
        }