private static List <GroupLocationScheduleCount> UpdateCache()
        {
            var output = new List <GroupLocationScheduleCount>();

            RockContext rockContext = new RockContext();

            AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            var attendances = attendanceOccurrenceService.Queryable()
                              .Where(ao => ao.OccurrenceDate == RockDateTime.Today)
                              .SelectMany(ao => ao.Attendees)
                              .Where(a => a.EndDateTime == null)
                              .GroupBy(a => new { a.Occurrence.GroupId, a.Occurrence.LocationId, a.Occurrence.ScheduleId })
                              .ToList();

            foreach (var attendance in attendances)
            {
                var glsc = new GroupLocationScheduleCount()
                {
                    GroupId         = attendance.Key.GroupId ?? 0,
                    LocationId      = attendance.Key.LocationId ?? 0,
                    ScheduleId      = attendance.Key.ScheduleId ?? 0,
                    PersonIds       = attendance.Select(a => a.PersonAlias?.PersonId ?? 0).ToList(),
                    InRoomPersonIds = attendance.Where(a => a.DidAttend == true).Select(a => a.PersonAlias?.PersonId ?? 0).ToList()
                };
                output.Add(glsc);
            }

            RockCache.AddOrUpdate(cacheKey, null, output, RockDateTime.Now.AddMinutes(10), Constants.CACHE_TAG);
            return(output);
        }
        /// <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 BlockActionResult SaveSchedule(PersonScheduleSignupDataBag schedule)
        {
            using (var rockContext = new RockContext())
            {
                var groupId    = new GroupService(rockContext).GetNoTracking(schedule.GroupGuid).Id;
                var locationId = new LocationService(rockContext).GetNoTracking(schedule.LocationGuid).Id;
                var scheduleId = new ScheduleService(rockContext).GetNoTracking(schedule.ScheduleGuid).Id;

                var attendanceOccurrence = new AttendanceOccurrenceService(rockContext).GetOrAdd(schedule.ScheduledDateTime.DateTime, groupId, locationId, scheduleId);
                var personAlias          = new PersonAliasService(rockContext).Get(CurrentPersonPrimaryAliasId);

                var attendanceService = new AttendanceService(rockContext);
                var attendance        = attendanceService.ScheduledPersonAddPending(CurrentPersonId, attendanceOccurrence.Id, personAlias);

                if (attendance == null)
                {
                    return(ActionBadRequest("Failed to schedule that particular date. Please try again."));
                }

                rockContext.SaveChanges();

                attendanceService.ScheduledPersonConfirm(attendance.Id);
                rockContext.SaveChanges();

                return(ActionOk());
            }
        }
 /// <summary>
 /// Initializes the services.
 /// </summary>
 /// <param name="rockContext">The rock context.</param>
 private void InitializeServices(RockContext rockContext)
 {
     _systemCommunicationService = new SystemCommunicationService(rockContext);
     _groupService                = new GroupService(rockContext);
     _groupMemberService          = new GroupMemberService(rockContext);
     _attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
 }
        /// <summary>
        /// Handles the Delete event of the gOccurrences control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void gOccurrences_Delete(object sender, RowEventArgs e)
        {
            var rockContext       = new RockContext();
            var occurenceService  = new AttendanceOccurrenceService(rockContext);
            var attendanceService = new AttendanceService(rockContext);
            var occurrence        = occurenceService.Get(e.RowKeyId);

            if (occurrence != null)
            {
                var locationId = occurrence.LocationId;

                string errorMessage;
                if (!occurenceService.CanDelete(occurrence, out errorMessage))
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Alert);
                    return;
                }

                // Delete the attendees for this occurrence since it is not a cascading delete
                var attendees = attendanceService.Queryable().Where(a => a.OccurrenceId == occurrence.Id);
                rockContext.BulkDelete <Attendance>(attendees);

                occurenceService.Delete(occurrence);
                rockContext.SaveChanges();

                if (locationId.HasValue)
                {
                    Rock.CheckIn.KioskLocationAttendance.Remove(locationId.Value);
                }
            }

            BindGrid();
        }
示例#6
0
        /// <summary>
        /// Gets the attendee data (for use in the grid and chart).
        /// </summary>
        /// <param name="rockContext">The RockContext</param>
        /// <returns>A list of <see cref="RSVPAttendee"/> objects representing the attendees of an occurrence.</returns>
        private List <RSVPAttendee> GetAttendees(RockContext rockContext)
        {
            List <RSVPAttendee> attendees = new List <RSVPAttendee>();
            List <int>          existingAttendanceRecords = new List <int>();

            int?occurrenceId = PageParameter(PageParameterKey.OccurrenceId).AsIntegerOrNull();

            if ((occurrenceId != null) && (occurrenceId != 0))
            {
                // Add RSVP responses for anyone who has an attendance record, already.
                var occurrenceService = new AttendanceOccurrenceService(rockContext);
                var occurrence        = occurrenceService.Get(occurrenceId.Value);
                var sortedAttendees   = occurrence.Attendees.OrderBy(a => a.PersonAlias.Person.LastName).ThenBy(a => a.PersonAlias.Person.FirstName);
                foreach (var attendee in sortedAttendees)
                {
                    RSVPAttendee rsvp = new RSVPAttendee();
                    rsvp.PersonId      = attendee.PersonAlias.PersonId;
                    rsvp.NickName      = attendee.PersonAlias.Person.NickName;
                    rsvp.LastName      = attendee.PersonAlias.Person.LastName;
                    rsvp.Accept        = (attendee.RSVP == Rock.Model.RSVP.Yes);
                    rsvp.Decline       = (attendee.RSVP == Rock.Model.RSVP.No);
                    rsvp.DeclineReason = attendee.DeclineReasonValueId;
                    rsvp.DeclineNote   = attendee.Note;
                    attendees.Add(rsvp);
                    existingAttendanceRecords.Add(attendee.PersonAlias.PersonId);
                }
            }

            return(attendees);
        }
        public virtual HttpResponseMessage CanSchedulePerson(int personId, int attendanceOccurrenceId, int?fromAttendanceOccurrenceId = null)
        {
            var rockContext       = new RockContext();
            var attendanceService = new AttendanceService(rockContext);

            var attendanceOccurrenceInfo = new AttendanceOccurrenceService(rockContext).GetSelect(attendanceOccurrenceId, s => new
            {
                s.ScheduleId,
                s.OccurrenceDate
            });

            if (attendanceOccurrenceInfo == null)
            {
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            var scheduleId     = attendanceOccurrenceInfo.ScheduleId;
            var occurrenceDate = attendanceOccurrenceInfo.OccurrenceDate;

            // Only count occurrences with active locations and active schedules as conflicting.
            var conflictingScheduledAttendancesQuery = attendanceService.Queryable().WhereDeducedIsActive();

            if (fromAttendanceOccurrenceId.HasValue)
            {
                // if person was dragged from one occurrence to another, we can exclude both source and target occurrences when detecting conflicts
                conflictingScheduledAttendancesQuery = conflictingScheduledAttendancesQuery
                                                       .Where(c => (c.OccurrenceId != attendanceOccurrenceId) && (c.OccurrenceId != fromAttendanceOccurrenceId.Value));
            }
            else
            {
                // if person was dragged from resources to an occurrence, we can exclude the target occurrences when detecting conflicts
                conflictingScheduledAttendancesQuery = conflictingScheduledAttendancesQuery
                                                       .Where(c => c.OccurrenceId != attendanceOccurrenceId);
            }

            // a conflict would be if the same person is requested/scheduled for another attendance within the same ScheduleId/Date
            conflictingScheduledAttendancesQuery = conflictingScheduledAttendancesQuery.Where(c =>
                                                                                              c.PersonAlias.PersonId == personId &&
                                                                                              (c.RequestedToAttend == true || c.ScheduledToAttend == true) &&
                                                                                              c.Occurrence.ScheduleId == scheduleId &&
                                                                                              c.Occurrence.OccurrenceDate == occurrenceDate);

            if (conflictingScheduledAttendancesQuery.Any())
            {
                var person        = new PersonService(rockContext).Get(personId);
                var firstConflict = conflictingScheduledAttendancesQuery.Select(s => new
                {
                    GroupName    = s.Occurrence.Group.Name,
                    LocationName = s.Occurrence.Location.Name
                }).FirstOrDefault();

                return(ControllerContext.Request.CreateErrorResponse(
                           HttpStatusCode.BadRequest,
                           $"{person} cannot be scheduled due a scheduling conflict with {firstConflict?.GroupName} in the {firstConflict?.LocationName}."));
            }

            return(new HttpResponseMessage(HttpStatusCode.OK));
        }
示例#8
0
        private void LoadRegistration()
        {
            var rockContext                 = new RockContext();
            var groupService                = new GroupService(rockContext);
            var attendanceService           = new AttendanceService(rockContext);
            var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);

            // get list of groups of this type
            var groups = groupService.Queryable()
                         .Where(g =>
                                g.GroupTypeId == _groupType.Id &&
                                g.IsActive == true)
                         .ToList();

            var groupIds = groups.Select(g => g.Id).ToList();

            // get listing of possible attendance for groups of this type
            var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(GetAttributeValue("DateRange") ?? "-1||");

            var attendanceOccurrences = attendanceOccurrenceService.Queryable()
                                        .Where(a =>
                                               a.GroupId.HasValue &&
                                               groupIds.Contains(a.GroupId.Value) &&
                                               a.OccurrenceDate >= dateRange.Start.Value &&
                                               a.OccurrenceDate <= dateRange.End.Value &&
                                               a.LocationId == _location.Id)
                                        .Distinct()
                                        .ToList();


            _schedules = attendanceOccurrences.Select(a => new ScheduleResult
            {
                Group    = a.Group,
                Schedule = a.Schedule,
                Date     = a.OccurrenceDate
            })
                         .Distinct()
                         .ToList();
            var occurrenceIds = attendanceOccurrences.Select(o => o.Id).ToList();

            // get personal schedules (things you already signed up for)
            _personalSchedules = attendanceService.Queryable()
                                 .Where(a =>
                                        occurrenceIds.Contains(a.OccurrenceId) &&
                                        a.PersonAlias.PersonId == CurrentPersonId &&
                                        a.RSVP == RSVP.Yes)
                                 .Select(a => new ScheduleResult
            {
                Group    = a.Occurrence.Group,
                Schedule = a.Occurrence.Schedule,
                Date     = a.StartDateTime
            })
                                 .Distinct()
                                 .ToList();

            rptScheduleDates.DataSource = _schedules.Select(s => s.Date.Date).Distinct();
            rptScheduleDates.DataBind();
        }
示例#9
0
        /// <summary>
        /// Handles the SaveClick event of the mdMovePerson 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 mdMovePerson_SaveClick(object sender, EventArgs e)
        {
            var attendanceId = ddlMovePersonSelectAttendance.SelectedValueAsId();

            if (attendanceId == null)
            {
                return;
            }

            var rockContext                 = new RockContext();
            var attendanceService           = new AttendanceService(rockContext);
            var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            var attendance = attendanceService.Get(attendanceId.Value);

            if (attendance == null)
            {
                return;
            }

            var selectedOccurrenceDate = attendance.Occurrence.OccurrenceDate;
            var selectedScheduleId     = ddlMovePersonSchedule.SelectedValueAsId();
            var selectedLocationId     = lpMovePersonLocation.SelectedValueAsId();
            var selectedGroupId        = ddlMovePersonGroup.SelectedValueAsId();

            if (!selectedLocationId.HasValue || !selectedGroupId.HasValue || !selectedScheduleId.HasValue)
            {
                return;
            }

            var location = NamedLocationCache.Get(selectedLocationId.Value);

            var locationFirmRoomThreshold = location?.FirmRoomThreshold;

            if (locationFirmRoomThreshold.HasValue)
            {
                // The totalAttended is the number of people still checked in (not people who have been checked-out)
                // not counting the current person who may already be checked in,
                // + the person we are trying to move
                var locationCount = attendanceService.GetByDateOnLocationAndSchedule(selectedOccurrenceDate, selectedLocationId.Value, selectedScheduleId.Value)
                                    .Where(a => a.EndDateTime == null && a.PersonAlias.PersonId != attendance.PersonAlias.PersonId).Count();

                if ((locationCount + 1) >= locationFirmRoomThreshold.Value)
                {
                    nbMovePersonLocationFull.Text    = $"The {location} has reached its hard threshold capacity and cannot be used for check-in.";
                    nbMovePersonLocationFull.Visible = true;
                    return;
                }
            }

            var newRoomsOccurrence = attendanceOccurrenceService.GetOrAdd(selectedOccurrenceDate, selectedGroupId, selectedLocationId, selectedScheduleId);

            attendance.OccurrenceId = newRoomsOccurrence.Id;
            rockContext.SaveChanges();

            mdMovePerson.Hide();
            BindGrid();
        }
示例#10
0
        /// <summary>
        /// Binds the grid and chart with attendee data.
        /// </summary>
        private void BindAttendeeGridAndChart(bool isExporting = false)
        {
            using (var rockContext = new RockContext())
            {
                int?occurrenceId = PageParameter(PageParameterKey.OccurrenceId).AsIntegerOrNull();
                if ((occurrenceId == null) || (occurrenceId == 0))
                {
                    occurrenceId = hfNewOccurrenceId.Value.AsIntegerOrNull();
                }

                if ((occurrenceId != null) && (occurrenceId != 0))
                {
                    var occurrenceService = new AttendanceOccurrenceService(rockContext);
                    var occurrence        = occurrenceService.Get(occurrenceId.Value);
                    gAttendees.ColumnsOfType <RockTemplateField>()
                    .First(c => c.HeaderText == "Decline Reason")
                    .Visible = occurrence.ShowDeclineReasons;
                    gAttendees.ColumnsOfType <RockTemplateField>()
                    .First(c => c.HeaderText == "Decline Note")
                    .Visible = occurrence.ShowDeclineReasons;
                }

                gAttendees.ColumnsOfType <BoolField>()
                .First(c => c.HeaderText == "Accept")
                .Visible = isExporting;
                gAttendees.ColumnsOfType <RockLiteralField>()
                .First(c => c.HeaderText == "Decline Reason")
                .Visible = isExporting;
                gAttendees.ColumnsOfType <BoolField>()
                .First(c => c.HeaderText == "Decline")
                .Visible = isExporting;


                var attendees       = GetAttendees(rockContext);
                int acceptCount     = attendees.Where(a => a.Accept).Count();
                int declineCount    = attendees.Where(a => a.Decline).Count();
                int noResponseCount = attendees.Count() - acceptCount - declineCount;
                RegisterDoughnutChartScript(acceptCount, declineCount, noResponseCount);

                _availableDeclineReasons = null;
                GetAvailableDeclineReasons();

                gAttendees.DataSource = attendees;
                gAttendees.DataBind();

                if (attendees.Count() < 1)
                {
                    lbSave.Visible = false;
                }
                else
                {
                    lbSave.Visible = true;
                }
            }
        }
示例#11
0
        /// <summary>
        /// Gets the data items to be included in the grid.
        /// </summary>
        /// <param name="groupId"></param>
        private List <RSVPListOccurrence> GetGroupRSVP(int groupId)
        {
            DateTime?  fromDateTime = drpDates.LowerValue;
            DateTime?  toDateTime   = drpDates.UpperValue;
            List <int> locationIds  = new List <int>();
            List <int> scheduleIds  = new List <int>();

            // Location Filter
            if (ddlLocation.Visible)
            {
                int?locationId = ddlLocation.SelectedValue.AsIntegerOrNull();
                if (locationId.HasValue)
                {
                    locationIds.Add(locationId.Value);
                }
            }

            //// Schedule Filter
            //if ( ddlSchedule.Visible )
            //{
            //    int? scheduleId = ddlSchedule.SelectedValue.AsIntegerOrNull();
            //    if ( scheduleId.HasValue )
            //    {
            //        scheduleIds.Add( scheduleId.Value );
            //    }
            //}

            var rockContext  = new RockContext();
            var groupService = new GroupService(rockContext);
            var group        = groupService.Get(groupId);

            //int invitedCount = group.ActiveMembers().Count();

            // Get all the occurrences for this group for the selected dates, location and schedule
            var occurrences = new AttendanceOccurrenceService(rockContext)
                              .GetGroupOccurrences(group, fromDateTime, toDateTime, locationIds, scheduleIds)
                              .Select(o => new RSVPListOccurrence(o))
                              .ToList();


            // Sort the occurrences
            List <RSVPListOccurrence> sortedOccurrences = null;

            if (gRSVPItems.SortProperty != null)
            {
                sortedOccurrences = occurrences.AsQueryable().Sort(gRSVPItems.SortProperty).ToList();
            }
            else
            {
                sortedOccurrences = occurrences.OrderByDescending(a => a.OccurrenceDate).ThenByDescending(a => a.StartTime).ToList();
            }

            return(sortedOccurrences);
        }
        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);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="GroupAttendedTransaction"/> class.
        /// </summary>
        /// <param name="entry">The entry.</param>
        public GroupAttendedTransaction(DbEntityEntry entry)
        {
            if (entry.State != EntityState.Deleted)
            {
                // Get the attendance record
                var attendance = entry.Entity as Attendance;

                // If attendance record is valid and the DidAttend is true (not null or false)
                if (attendance != null && (attendance.DidAttend == true))
                {
                    // Save for all adds
                    bool valid = entry.State == EntityState.Added;

                    // If not an add, check previous DidAttend value
                    if (!valid)
                    {
                        var dbProperty = entry.Property("DidAttend");
                        if (dbProperty != null)
                        {
                            // Only use changes where DidAttend was previously not true
                            valid = !(dbProperty.OriginalValue as bool? ?? false);
                        }
                    }

                    if (valid)
                    {
                        var occ = attendance.Occurrence;
                        if (occ == null)
                        {
                            occ = new AttendanceOccurrenceService(new RockContext()).Get(attendance.OccurrenceId);
                        }

                        if (occ != null)
                        {
                            // Save the values
                            GroupId            = occ.GroupId;
                            AttendanceDateTime = occ.OccurrenceDate;
                            PersonAliasId      = attendance.PersonAliasId;

                            if (occ.Group != null)
                            {
                                GroupTypeId = occ.Group.GroupTypeId;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Gets the occurrences query.
        /// </summary>
        /// <param name="includeSchedule">if set to <c>true</c> [include schedule].</param>
        /// <returns></returns>
        private IQueryable <AttendanceOccurrence> GetOccurrencesQuery(bool includeSchedule = true)
        {
            // get the occurrences for SelectedDate with Groups
            var occurrenceQuery = new AttendanceOccurrenceService(_rockContext)
                                  .Queryable()
                                  .AsNoTracking()
                                  .Where(o => o.OccurrenceDate == SelectedDate.Value && o.GroupId.HasValue);

            // if filtering by schedule
            if (includeSchedule && SelectedSchedule.IsNotNullOrWhiteSpace())
            {
                var scheduleId = SelectedSchedule.AsInteger();
                occurrenceQuery = occurrenceQuery.Where(o => o.ScheduleId.HasValue && o.ScheduleId.Value == scheduleId);
            }

            return(occurrenceQuery);
        }
示例#15
0
        internal static AttendanceOccurrence GetOccurrenceForLocation(RockContext rockContext, Location location)
        {
            if (IsSubRoom(location))
            {
                location = location.ParentLocation;
            }

            AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            var occurrences = attendanceOccurrenceService.Queryable()
                              .Where(o => o.OccurrenceDate == RockDateTime.Now.Date && o.LocationId == location.Id).ToList();
            var volunteerOccurrences = occurrences.Where(o => OccurrenceCache.GetVolunteerOccurrences().Select(oc => oc.GroupId).Contains(o.GroupId ?? 0)).FirstOrDefault();

            if (volunteerOccurrences != null)
            {
                return(volunteerOccurrences);
            }
            return(null);
        }
示例#16
0
        public List <GroupOccurrenceResponse> GetFutureGroupOccurrences(int groupId, DateTime?toDateTime = null, string locationIds = null, string scheduleIds = null)
        {
            using (var rockContext = new RockContext())
            {
                rockContext.Configuration.ProxyCreationEnabled = false;
                var group = new GroupService(rockContext).Get(groupId);

                var occurrences = new AttendanceOccurrenceService(rockContext)
                                  .GetFutureGroupOccurrences(group, toDateTime, locationIds, scheduleIds);

                var response = new List <GroupOccurrenceResponse>();
                foreach (var occurrence in occurrences)
                {
                    response.Add(new GroupOccurrenceResponse(occurrence));
                }
                return(response);
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        /// <summary>
        /// Gets a list of future occurrences within the date range of the specified offset with RSVP responses for a <see cref="Group"/>.  Eager loads Attendees and
        /// attached Person records.
        /// </summary>
        /// <param name="group">The <see cref="Group"/>.</param>
        /// <param name="offsetDays">The number of days prior to the RSVP occurrence that a reminder should be sent.</param>
        /// <param name="rockContext">The <see cref="RockContext"/>.</param>
        /// <returns>A list of <see cref="AttendanceOccurrence"/> objects.</returns>
        private List <AttendanceOccurrence> GetOccurrencesForGroup(Group group, int offsetDays, RockContext rockContext)
        {
            // Calculate correct date range from the RSVP Offset.
            DateTime startDate = DateTime.Today.AddDays(offsetDays);
            DateTime endDate   = startDate.AddDays(1);

            // This can't use WithNoTracking because the sms service tries to access the PrimaryAliasId
            // which links to the Aliases property, but when we try to at the Aliases property to the include list
            // we get an "The RelatedEnd with role name X has already been loaded" error because it has already
            // been loaded with the PersonAlias object, however removing the AsNoTracking() resolves this issue.
            // you can read more about it here:
            // https://stackoverflow.com/questions/46038016/the-relatedend-with-role-name-x-has-already-been-loaded
            var rsvpOccurrences = new AttendanceOccurrenceService(rockContext)
                                  .Queryable("Attendees,Attendees.PersonAlias.Person")
                                  .Where(o => o.GroupId == group.Id)
                                  .Where(o => o.OccurrenceDate >= startDate)                    // OccurrenceDate must be greater than startDate (the beginning of the day from the offset).
                                  .Where(o => o.OccurrenceDate < endDate)                       // OccurrenceDate must be less than endDate (the end of the day from the offset).
                                  .Where(o => o.Attendees.Where(a => a.RSVP == RSVP.Yes).Any()) // Occurrence must have attendees who responded "Yes".
                                  .ToList();

            return(rsvpOccurrences);
        }
示例#20
0
        /// <summary>
        /// Removes the groups with attendence data.
        /// </summary>
        /// <param name="occurrences">The occurrences.</param>
        /// <param name="startDate">The start date.</param>
        /// <param name="endDate">The end date.</param>
        /// <param name="rockContext">The rock context.</param>
        private void RemoveGroupsWithAttendenceData(Dictionary <int, List <DateTime> > occurrences, DateTime startDate, DateTime endDate, RockContext rockContext)
        {
            var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            var occurrencesWithAttendence   = attendanceOccurrenceService
                                              .Queryable()
                                              .AsNoTracking()
                                              .DateInRange(startDate, endDate)
                                              .GroupIdsInList(occurrences.Keys.ToList())
                                              .HasScheduleId()
                                              .HasAttendeesOrDidNotOccur()
                                              .Select(a => new
            {
                GroupId = a.GroupId.Value,
                a.OccurrenceDate
            })
                                              .Distinct()
                                              .ToList();

            foreach (var occurrence in occurrencesWithAttendence)
            {
                occurrences[occurrence.GroupId].RemoveAll(d => d.Date == occurrence.OccurrenceDate.Date);
            }
        }
示例#21
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap   = context.JobDetail.JobDataMap;
            var        groupType = GroupTypeCache.Get(dataMap.GetString("GroupType").AsGuid());
            int        attendanceRemindersSent = 0;
            int        errorCount    = 0;
            var        errorMessages = new List <string>();

            if (groupType.TakesAttendance && groupType.SendAttendanceReminder)
            {
                // Get the occurrence dates that apply
                var dates = new List <DateTime>();
                dates.Add(RockDateTime.Today);
                try
                {
                    string[] reminderDays = dataMap.GetString("SendReminders").Split(',');
                    foreach (string reminderDay in reminderDays)
                    {
                        if (reminderDay.Trim().IsNotNullOrWhiteSpace())
                        {
                            var reminderDate = RockDateTime.Today.AddDays(0 - Convert.ToInt32(reminderDay));
                            if (!dates.Contains(reminderDate))
                            {
                                dates.Add(reminderDate);
                            }
                        }
                    }
                }
                catch { }

                var rockContext                 = new RockContext();
                var groupService                = new GroupService(rockContext);
                var groupMemberService          = new GroupMemberService(rockContext);
                var scheduleService             = new ScheduleService(rockContext);
                var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);

                var startDate = dates.Min();
                var endDate   = dates.Max().AddDays(1);

                // Find all 'occurrences' for the groups that occur on the affected dates
                var occurrences = new Dictionary <int, List <DateTime> >();
                foreach (var group in groupService
                         .Queryable("Schedule").AsNoTracking()
                         .Where(g =>
                                g.GroupTypeId == groupType.Id &&
                                g.IsActive &&
                                g.Schedule != null &&
                                g.Members.Any(m =>
                                              m.GroupMemberStatus == GroupMemberStatus.Active &&
                                              m.GroupRole.IsLeader &&
                                              m.Person.Email != null &&
                                              m.Person.Email != String.Empty)))
                {
                    // Add the group
                    occurrences.Add(group.Id, new List <DateTime>());

                    // Check for a iCal schedule
                    if (!string.IsNullOrWhiteSpace(group.Schedule.iCalendarContent))
                    {
                        // If schedule has an iCal schedule, get occurrences between first and last dates
                        foreach (var occurrence in group.Schedule.GetOccurrences(startDate, endDate))
                        {
                            var startTime = occurrence.Period.StartTime.Value;
                            if (dates.Contains(startTime.Date))
                            {
                                occurrences[group.Id].Add(startTime);
                            }
                        }
                    }
                    else
                    {
                        // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week
                        if (group.Schedule.WeeklyDayOfWeek.HasValue)
                        {
                            foreach (var date in dates)
                            {
                                if (date.DayOfWeek == group.Schedule.WeeklyDayOfWeek.Value)
                                {
                                    var startTime = date;
                                    if (group.Schedule.WeeklyTimeOfDay.HasValue)
                                    {
                                        startTime = startTime.Add(group.Schedule.WeeklyTimeOfDay.Value);
                                    }
                                    occurrences[group.Id].Add(startTime);
                                }
                            }
                        }
                    }
                }

                // Remove any occurrences during group type exclusion date ranges
                foreach (var exclusion in groupType.GroupScheduleExclusions)
                {
                    if (exclusion.Start.HasValue && exclusion.End.HasValue)
                    {
                        foreach (var keyVal in occurrences)
                        {
                            foreach (var occurrenceDate in keyVal.Value.ToList())
                            {
                                if (occurrenceDate >= exclusion.Start.Value &&
                                    occurrenceDate < exclusion.End.Value.AddDays(1))
                                {
                                    keyVal.Value.Remove(occurrenceDate);
                                }
                            }
                        }
                    }
                }

                // Remove any 'occurrences' that already have attendance data entered
                foreach (var occurrence in attendanceOccurrenceService
                         .Queryable().AsNoTracking()
                         .Where(a =>
                                a.OccurrenceDate >= startDate &&
                                a.OccurrenceDate < endDate &&
                                a.GroupId.HasValue &&
                                occurrences.Keys.Contains(a.GroupId.Value) &&
                                a.ScheduleId.HasValue &&
                                (a.Attendees.Any() || (a.DidNotOccur.HasValue && a.DidNotOccur.Value)))
                         .Select(a => new
                {
                    GroupId = a.GroupId.Value,
                    a.OccurrenceDate
                })
                         .Distinct()
                         .ToList())
                {
                    occurrences[occurrence.GroupId].RemoveAll(d => d.Date == occurrence.OccurrenceDate.Date);
                }

                // Get the groups that have occurrences
                var groupIds = occurrences.Where(o => o.Value.Any()).Select(o => o.Key).ToList();

                // Get the leaders of those groups
                var leaders = groupMemberService
                              .Queryable("Group,Person").AsNoTracking()
                              .Where(m =>
                                     groupIds.Contains(m.GroupId) &&
                                     m.GroupMemberStatus == GroupMemberStatus.Active &&
                                     m.GroupRole.IsLeader &&
                                     m.Person.Email != null &&
                                     m.Person.Email != string.Empty)
                              .ToList();

                // Loop through the leaders
                foreach (var leader in leaders)
                {
                    foreach (var group in occurrences.Where(o => o.Key == leader.GroupId))
                    {
                        var mergeObjects = Rock.Lava.LavaHelper.GetCommonMergeFields(null, leader.Person);
                        mergeObjects.Add("Person", leader.Person);
                        mergeObjects.Add("Group", leader.Group);
                        mergeObjects.Add("Occurrence", group.Value.Max());

                        var recipients = new List <RecipientData>();
                        recipients.Add(new RecipientData(leader.Person.Email, mergeObjects));

                        var emailMessage = new RockEmailMessage(dataMap.GetString("SystemEmail").AsGuid());
                        emailMessage.SetRecipients(recipients);
                        var errors = new List <string>();
                        emailMessage.Send(out errors);

                        if (errors.Any())
                        {
                            errorCount += errors.Count;
                            errorMessages.AddRange(errors);
                        }
                        else
                        {
                            attendanceRemindersSent++;
                        }
                    }
                }
            }

            context.Result = string.Format("{0} attendance reminders sent", attendanceRemindersSent);
            if (errorMessages.Any())
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine();
                sb.Append(string.Format("{0} Errors: ", errorCount));
                errorMessages.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                string errors = sb.ToString();
                context.Result += errors;
                var         exception = new Exception(errors);
                HttpContext context2  = HttpContext.Current;
                ExceptionLogService.LogException(exception, context2);
                throw exception;
            }
        }
示例#22
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The workflow action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null)
            {
                bool loadAll = GetAttributeValue(action, "LoadAll").AsBoolean();

                foreach (var family in checkInState.CheckIn.GetFamilies(true))
                {
                    foreach (var person in family.GetPeople(!loadAll))
                    {
                        foreach (var groupType in person.GetGroupTypes(!loadAll).ToList())
                        {
                            var kioskGroupType = checkInState.Kiosk.ActiveGroupTypes(checkInState.ConfiguredGroupTypes)
                                                 .Where(g => g.GroupType.Id == groupType.GroupType.Id)
                                                 .FirstOrDefault();

                            if (kioskGroupType != null)
                            {
                                foreach (var group in groupType.GetGroups(!loadAll))
                                {
                                    var closedGroupLocationIds = new AttendanceOccurrenceService(rockContext)
                                                                 .Queryable()
                                                                 .AsNoTracking()
                                                                 .Where(o =>
                                                                        o.GroupId == group.Group.Id &&
                                                                        o.OccurrenceDate == RockDateTime.Today)
                                                                 .WhereAttributeValue(rockContext, "rocks.kfs.OccurrenceClosed", "True")
                                                                 .Select(l => l.LocationId)
                                                                 .ToList();

                                    var loadBalance = group.Group.GetAttributeValue("rocks.kfs.LoadBalanceLocations").AsBoolean();
                                    if (loadBalance && loadAll)
                                    {
                                        group.Locations.Clear();
                                    }

                                    var locationAttendance = new Dictionary <CheckInLocation, int>();

                                    foreach (var kioskGroup in kioskGroupType.KioskGroups
                                             .Where(g => g.Group.Id == group.Group.Id && g.IsCheckInActive)
                                             .ToList())
                                    {
                                        foreach (var kioskLocation in kioskGroup.KioskLocations.Where(l => l.IsCheckInActive && l.IsActiveAndNotFull && !closedGroupLocationIds.Contains(l.Location.Id)))
                                        {
                                            if (!group.Locations.Any(l => l.Location.Id == kioskLocation.Location.Id))
                                            {
                                                var checkInLocation = new CheckInLocation();
                                                checkInLocation.Location = kioskLocation.Location.Clone(false);
                                                checkInLocation.Location.CopyAttributesFrom(kioskLocation.Location);
                                                checkInLocation.CampusId = kioskLocation.CampusId;
                                                checkInLocation.Order    = kioskLocation.Order;
                                                locationAttendance.Add(checkInLocation, KioskLocationAttendance.Get(checkInLocation.Location.Id).CurrentCount);
                                            }
                                        }
                                    }

                                    if (loadBalance)
                                    {
                                        var sortedLocationAttendance = locationAttendance.ToList();
                                        sortedLocationAttendance.Sort((x, y) => x.Key.Location.Name.CompareTo(y.Key.Location.Name));
                                        sortedLocationAttendance.Sort((x, y) => x.Value.CompareTo(y.Value));
                                        var order = 0;
                                        foreach (var checkInLocationPair in sortedLocationAttendance)
                                        {
                                            var checkInLocation = checkInLocationPair.Key;
                                            checkInLocation.Order = order;
                                            group.Locations.Add(checkInLocation);

                                            order++;
                                        }
                                    }
                                    else
                                    {
                                        group.Locations.AddRange(locationAttendance.Select(l => l.Key).ToList());
                                    }
                                }
                            }
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGrid()
        {
            if (_group != null)
            {
                lHeading.Text = _group.Name;

                DateTime?  fromDateTime = drpDates.LowerValue;
                DateTime?  toDateTime   = drpDates.UpperValue;
                List <int> locationIds  = new List <int>();
                List <int> scheduleIds  = new List <int>();

                // Location Filter
                if (ddlLocation.Visible)
                {
                    string locValue = ddlLocation.SelectedValue;
                    if (locValue.StartsWith("P"))
                    {
                        int?parentLocationId = locValue.Substring(1).AsIntegerOrNull();
                        if (parentLocationId.HasValue)
                        {
                            locationIds = new LocationService(_rockContext)
                                          .GetAllDescendents(parentLocationId.Value)
                                          .Select(l => l.Id)
                                          .ToList();
                        }
                    }
                    else
                    {
                        int?locationId = locValue.AsIntegerOrNull();
                        if (locationId.HasValue)
                        {
                            locationIds.Add(locationId.Value);
                        }
                    }
                }

                // Schedule Filter
                if (ddlSchedule.Visible && ddlSchedule.SelectedValue != "0")
                {
                    scheduleIds.Add(ddlSchedule.SelectedValueAsInt() ?? 0);
                }

                // Get all the occurrences for this group for the selected dates, location and schedule
                var occurrences = new AttendanceOccurrenceService(_rockContext)
                                  .GetGroupOccurrences(_group, fromDateTime, toDateTime, locationIds, scheduleIds)
                                  .Select(o => new AttendanceListOccurrence(o))
                                  .ToList();

                var locationService = new LocationService(_rockContext);

                // Check to see if filtering by campus, and if so, only select those occurrences who's
                // location is associated with that campus (or not associated with any campus)
                int?campusId = bddlCampus.SelectedValueAsInt();
                if (campusId.HasValue)
                {
                    // If campus filter is selected, load all the descendent locations for each campus into a dictionary
                    var locCampus = new Dictionary <int, int>();
                    foreach (var campus in CampusCache.All().Where(c => c.LocationId.HasValue))
                    {
                        locCampus.AddOrIgnore(campus.LocationId.Value, campus.Id);
                        foreach (var locId in locationService.GetAllDescendentIds(campus.LocationId.Value))
                        {
                            locCampus.AddOrIgnore(locId, campus.Id);
                        }
                    }

                    // Using that dictionary, set the campus id for each occurrence
                    foreach (var occ in occurrences)
                    {
                        if (occ.LocationId.HasValue && locCampus.ContainsKey(occ.LocationId.Value))
                        {
                            occ.CampusId = locCampus[occ.LocationId.Value];
                        }
                    }

                    // Remove the occurrences that are associated with another campus
                    occurrences = occurrences
                                  .Where(o =>
                                         !o.CampusId.HasValue ||
                                         o.CampusId.Value == campusId.Value)
                                  .ToList();
                }

                // Update the Parent Location path
                foreach (int parentLocationId in occurrences
                         .Where(o => o.ParentLocationId.HasValue)
                         .Select(o => o.ParentLocationId.Value)
                         .Distinct())
                {
                    string parentLocationPath = locationService.GetPath(parentLocationId);
                    foreach (var occ in occurrences
                             .Where(o =>
                                    o.ParentLocationId.HasValue &&
                                    o.ParentLocationId.Value == parentLocationId))
                    {
                        occ.ParentLocationPath = parentLocationPath;
                    }
                }

                // Sort the occurrences
                SortProperty sortProperty = gOccurrences.SortProperty;
                List <AttendanceListOccurrence> sortedOccurrences = null;
                if (sortProperty != null)
                {
                    if (sortProperty.Property == "LocationPath,LocationName")
                    {
                        if (sortProperty.Direction == SortDirection.Ascending)
                        {
                            sortedOccurrences = occurrences.OrderBy(o => o.ParentLocationPath).ThenBy(o => o.LocationName).ToList();
                        }
                        else
                        {
                            sortedOccurrences = occurrences.OrderByDescending(o => o.ParentLocationPath).ThenByDescending(o => o.LocationName).ToList();
                        }
                    }
                    else
                    {
                        sortedOccurrences = occurrences.AsQueryable().Sort(sortProperty).ToList();
                    }
                }
                else
                {
                    sortedOccurrences = occurrences.OrderByDescending(a => a.OccurrenceDate).ThenByDescending(a => a.StartTime).ToList();
                }

                gOccurrences.DataSource = sortedOccurrences;
                gOccurrences.DataBind();
            }
        }
示例#24
0
        /// <summary>
        /// Builds the status board.
        /// </summary>
        private void BuildStatusBoard()
        {
            lGroupStatusTableHTML.Text = string.Empty;

            int numberOfWeeks = GetSelectedNumberOfWeeks();

            List <int> selectedGroupIds = GetSelectedGroupIds();
            var        rockContext      = new RockContext();
            var        groupsQuery      = new GroupService(rockContext).GetByIds(selectedGroupIds).Where(a => a.GroupType.IsSchedulingEnabled == true);

            nbGroupsWarning.Visible = false;
            if (!groupsQuery.Any())
            {
                nbGroupsWarning.Text = "Please select at least one group.";
                nbGroupsWarning.NotificationBoxType = NotificationBoxType.Warning;
                nbGroupsWarning.Visible             = true;
                return;
            }

            var groupLocationService = new GroupLocationService(rockContext);
            var groupLocationsQuery  = groupLocationService.Queryable().Where(a => selectedGroupIds.Contains(a.GroupId) && a.Group.GroupType.IsSchedulingEnabled == true);

            // get all the schedules that are in use by at least one of the GroupLocations
            var groupsScheduleList = groupLocationsQuery.SelectMany(a => a.Schedules).Distinct().AsNoTracking().ToList();

            if (!groupsScheduleList.Any())
            {
                nbGroupsWarning.Text = "The selected groups don't have any location schedules configured.";
                nbGroupsWarning.NotificationBoxType = NotificationBoxType.Warning;
                nbGroupsWarning.Visible             = true;
                return;
            }

            // get the next N sundayDates
            List <DateTime> sundayDateList = GetSundayDateList(numberOfWeeks);

            // build the list of scheduled times for the next n weeks
            List <ScheduleOccurrenceDate> scheduleOccurrenceDateList = new List <ScheduleOccurrenceDate>();
            var currentDate = RockDateTime.Today;

            foreach (var sundayDate in sundayDateList)
            {
                foreach (var schedule in groupsScheduleList)
                {
                    var sundayWeekStart = sundayDate.AddDays(-6);

                    // get all the occurrences for the selected week for this scheduled (It could be more than once a week if it is a daily scheduled, or it might not be in the selected week if it is every 2 weeks, etc)
                    var scheduledDateTimeList = schedule.GetScheduledStartTimes(sundayWeekStart, sundayDate.AddDays(1));
                    foreach (var scheduledDateTime in scheduledDateTimeList)
                    {
                        if (scheduledDateTime >= currentDate)
                        {
                            scheduleOccurrenceDateList.Add(new ScheduleOccurrenceDate {
                                Schedule = schedule, ScheduledDateTime = scheduledDateTime
                            });
                        }
                    }
                }
            }

            scheduleOccurrenceDateList = scheduleOccurrenceDateList.OrderBy(a => a.ScheduledDateTime).ToList();

            var latestOccurrenceDate = sundayDateList.Max();

            var scheduledOccurrencesQuery = new AttendanceOccurrenceService(rockContext).Queryable().Where(a => a.GroupId.HasValue && a.LocationId.HasValue && a.ScheduleId.HasValue && selectedGroupIds.Contains(a.GroupId.Value));

            scheduledOccurrencesQuery = scheduledOccurrencesQuery.Where(a => a.OccurrenceDate >= currentDate && a.OccurrenceDate <= latestOccurrenceDate);

            var occurrenceScheduledAttendancesList = scheduledOccurrencesQuery.Select(ao => new
            {
                Occurrence         = ao,
                ScheduledAttendees = ao.Attendees.Where(a => a.RequestedToAttend == true || a.ScheduledToAttend == true).Select(a => new
                {
                    ScheduledPerson = a.PersonAlias.Person,
                    a.RequestedToAttend,
                    a.ScheduledToAttend,
                    a.RSVP
                })
            }).ToList();

            StringBuilder sbTable = new StringBuilder();

            // start of table
            sbTable.AppendLine("<table class='table schedule-status-board js-schedule-status-board'>");

            sbTable.AppendLine("<thead class='schedule-status-board-header js-schedule-status-board-header'>");
            sbTable.AppendLine("<tr>");

            var tableHeaderLavaTemplate = @"
{%- comment -%}empty column for group/location names{%- endcomment -%}
<th scope='col'></th>
{% for scheduleOccurrenceDate in ScheduleOccurrenceDateList %}
    <th scope='col'>
        <span class='date'>{{ scheduleOccurrenceDate.ScheduledDateTime | Date:'MMM d, yyyy'  }}</span>
        <br />
        <span class='day-time'>{{ scheduleOccurrenceDate.Schedule.Name }}</span>
    </th>
{% endfor %}
";

            var headerMergeFields = new Dictionary <string, object> {
                { "ScheduleOccurrenceDateList", scheduleOccurrenceDateList }
            };
            string tableHeaderHtml = tableHeaderLavaTemplate.ResolveMergeFields(headerMergeFields);

            sbTable.Append(tableHeaderHtml);
            sbTable.AppendLine("</tr>");
            sbTable.AppendLine("</thead>");

            var groupLocationsList = groupsQuery.Where(g => g.GroupLocations.Any()).OrderBy(a => a.Order).ThenBy(a => a.Name).Select(g => new
            {
                Group = g,
                LocationScheduleCapacitiesList = g.GroupLocations.OrderBy(gl => gl.Order).ThenBy(gl => gl.Location.Name).Select(a => new
                {
                    ScheduleCapacitiesList = a.GroupLocationScheduleConfigs.Select(sc =>
                                                                                   new ScheduleCapacities
                    {
                        ScheduleId      = sc.ScheduleId,
                        MinimumCapacity = sc.MinimumCapacity,
                        DesiredCapacity = sc.DesiredCapacity,
                        MaximumCapacity = sc.MaximumCapacity
                    }),
                    a.Location
                }).ToList()
            }).ToList();

            var columnsCount = scheduleOccurrenceDateList.Count() + 1;

            foreach (var groupLocations in groupLocationsList)
            {
                var           group            = groupLocations.Group;
                StringBuilder sbGroupLocations = new StringBuilder();
                sbGroupLocations.AppendLine(string.Format("<tbody class='group-locations js-group-locations' data-group-id='{0}' data-locations-expanded='1'>", group.Id));

                // group header row
                sbGroupLocations.AppendLine("<tr class='group-heading js-group-header thead-dark clickable' >");
                sbGroupLocations.AppendLine(string.Format("<th></th><th colspan='{0}'><i class='fa fa-chevron-down'></i> {1}</th>", columnsCount - 1, group.Name));
                sbGroupLocations.AppendLine("</tr>");

                // group/schedule+locations
                var locationScheduleCapacitiesList = groupLocations.LocationScheduleCapacitiesList;
                foreach (var locationScheduleCapacities in locationScheduleCapacitiesList)
                {
                    var location = locationScheduleCapacities.Location;
                    var scheduleCapacitiesLookup = locationScheduleCapacities.ScheduleCapacitiesList.ToDictionary(k => k.ScheduleId, v => v);
                    sbGroupLocations.AppendLine("<tr class='location-row js-location-row'>");

                    sbGroupLocations.AppendLine(string.Format("<td class='location' scope='row' data-location-id='{0}'><div>{1}</div></td>", location.Id, location.Name));

                    foreach (var scheduleOccurrenceDate in scheduleOccurrenceDateList)
                    {
                        var capacities = scheduleCapacitiesLookup.GetValueOrNull(scheduleOccurrenceDate.Schedule.Id) ?? new ScheduleCapacities();

                        var scheduleLocationStatusHtmlFormat =
                            @"<ul class='location-scheduled-list' data-capacity-min='{1}' data-capacity-desired='{2}' data-capacity-max='{3}' data-scheduled-count='{4}'>
    {0}
</ul>";
                        StringBuilder sbScheduledListHtml            = new StringBuilder();
                        var           occurrenceScheduledAttendances = occurrenceScheduledAttendancesList
                                                                       .FirstOrDefault(ao =>
                                                                                       ao.Occurrence.OccurrenceDate == scheduleOccurrenceDate.OccurrenceDate &&
                                                                                       ao.Occurrence.GroupId == groupLocations.Group.Id &&
                                                                                       ao.Occurrence.ScheduleId == scheduleOccurrenceDate.Schedule.Id &&
                                                                                       ao.Occurrence.LocationId == location.Id);

                        int scheduledCount = 0;

                        if (occurrenceScheduledAttendances != null && occurrenceScheduledAttendances.ScheduledAttendees.Any())
                        {
                            // sort so that it is Yes, then Pending, then Denied
                            var scheduledPersonList = occurrenceScheduledAttendances
                                                      .ScheduledAttendees
                                                      .OrderBy(a => a.RSVP == RSVP.Yes ? 0 : 1)
                                                      .ThenBy(a => (a.RSVP == RSVP.Maybe || a.RSVP == RSVP.Unknown) ? 0 : 1)
                                                      .ThenBy(a => a.RSVP == RSVP.No ? 0 : 1)
                                                      .ThenBy(a => a.ScheduledPerson.LastName)
                                                      .ToList();

                            foreach (var scheduledPerson in scheduledPersonList)
                            {
                                ScheduledAttendanceItemStatus status = ScheduledAttendanceItemStatus.Pending;
                                if (scheduledPerson.RSVP == RSVP.No)
                                {
                                    status = ScheduledAttendanceItemStatus.Declined;
                                }
                                else if (scheduledPerson.ScheduledToAttend == true)
                                {
                                    status = ScheduledAttendanceItemStatus.Confirmed;
                                }

                                sbScheduledListHtml.AppendLine(string.Format("<li class='slot person {0}' data-status='{0}'><i class='status-icon'></i><span class='person-name'>{1}</span></li>", status.ConvertToString(false).ToLower(), scheduledPerson.ScheduledPerson));
                            }

                            scheduledCount = scheduledPersonList.Where(a => a.RSVP != RSVP.No).Count();
                        }

                        if (capacities.DesiredCapacity.HasValue && scheduledCount < capacities.DesiredCapacity.Value)
                        {
                            var countNeeded = capacities.DesiredCapacity.Value - scheduledCount;
                            sbScheduledListHtml.AppendLine(string.Format("<li class='slot persons-needed empty-slot'>{0} {1} needed</li>", countNeeded, "person".PluralizeIf(countNeeded != 1)));

                            // add empty slots if we are under the desired count (not including the slot for the 'persons-needed' li)
                            var emptySlotsToAdd = countNeeded - 1;
                            while (emptySlotsToAdd > 0)
                            {
                                sbScheduledListHtml.AppendLine("<li class='slot empty-slot'></li>");
                                emptySlotsToAdd--;
                            }
                        }

                        var scheduledLocationsStatusHtml = string.Format(scheduleLocationStatusHtmlFormat, sbScheduledListHtml, capacities.MinimumCapacity, capacities.DesiredCapacity, capacities.MaximumCapacity, scheduledCount);

                        sbGroupLocations.AppendLine(string.Format("<td class='schedule-location js-schedule-location' data-schedule-id='{0}'><div>{1}</div></td>", scheduleOccurrenceDate.Schedule.Id, scheduledLocationsStatusHtml));
                    }

                    sbGroupLocations.AppendLine("</tr>");
                }

                sbGroupLocations.AppendLine("</tbody>");

                sbTable.Append(sbGroupLocations.ToString());
            }

            // closing divs for main header
            sbTable.AppendLine("</tr>");
            sbTable.AppendLine("</thead>");

            // closing divs for table
            sbTable.AppendLine("</table>");

            lGroupStatusTableHTML.Text = sbTable.ToString();
        }
示例#25
0
        private void BindGrid()
        {
            gReport.Visible        = false;
            nbNotification.Visible = false;
            RockContext rockContext = new RockContext();
            AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            AttendanceService           attendanceService           = new AttendanceService(rockContext);
            LocationService             locationService             = new LocationService(rockContext);
            ScheduleService             scheduleService             = new ScheduleService(rockContext);

            var location = lpLocation.Location;

            if (location == null || dpDate.SelectedDate == null)
            {
                return;
            }

            //Set the name of the export
            List <string> locationNameList  = new List <string>();
            var           locationForExport = location;

            while (true)
            {
                if (locationForExport == null)
                {
                    break;
                }
                locationNameList.Add(locationForExport.Name);
                locationForExport = locationForExport.ParentLocation;
            }

            locationNameList.Reverse();
            gReport.ExportTitleName = dpDate.SelectedDate.Value.ToString("MM/dd/yyyy") +
                                      "  -- ";

            if (tgChildLocations.Checked)
            {
                gReport.ExportTitleName += " Child Locations of: ";
            }
            gReport.ExportTitleName += string.Join(" > ", locationNameList);
            var schedule = scheduleService.Get(spSchedule.SelectedValueAsId() ?? 0);

            if (schedule != null)
            {
                gReport.ExportTitleName += " (" + schedule.Name + ")";
            }

            var fileName = dpDate.SelectedDate.Value.ToString("MM.dd.yyyy") +
                           (tgChildLocations.Checked ? "_ChildLocationsOf_" : "_") +
                           location.Name;

            if (schedule != null)
            {
                fileName += "_" + schedule.Name;
            }

            gReport.ExportFilename = fileName;



            //Get child locations if needed
            var locationIds = new List <int> {
                location.Id
            };

            if (tgChildLocations.Checked)
            {
                List <Location> childLocations = GetChildLocations(location);
                locationIds.AddRange(childLocations.Select(l => l.Id));
            }

            var attendanceOccurrencesQry = attendanceOccurrenceService
                                           .Queryable()
                                           .Where(ao => ao.OccurrenceDate == (dpDate.SelectedDate ?? RockDateTime.Now))
                                           .Where(ao => locationIds.Contains(ao.LocationId ?? 0))
                                           .Where(ao => ao.Group != null && ao.Schedule != null);


            var scheduleId = spSchedule.SelectedValueAsId();

            if (scheduleId != null)
            {
                attendanceOccurrencesQry = attendanceOccurrencesQry.Where(ao => ao.ScheduleId == scheduleId);
            }

            var attendanceOccurrences = attendanceOccurrencesQry
                                        .Select(ao => ao.Id)
                                        .ToList();

            var attendances = attendanceService.Queryable("PersonAlias, PersonAlias.Person, Occurrence, Occurrence.Group, Occurrence.Location, Occurrence.Schedule, Device")
                              .Where(a => attendanceOccurrences.Contains(a.OccurrenceId))
                              .ToList();

            if (!attendances.Any())
            {
                nbNotification.Visible = true;
                nbNotification.Text    = "Could not find any attendances with these parameters";
                return;
            }

            var records           = new List <AttendanceRecord>();
            var volunteerGroupIds = KioskCountUtility.GetVolunteerGroupIds();

            foreach (var attendance in attendances)
            {
                var record = new AttendanceRecord
                {
                    PersonId    = attendance.PersonAlias.Person.Id,
                    PersonName  = attendance.PersonAlias.Person.FullNameReversed,
                    Age         = attendance.PersonAlias.Person.Age,
                    Schedule    = attendance.Occurrence.Schedule.Name,
                    Location    = attendance.Occurrence.Location.Name,
                    Group       = attendance.Occurrence.Group.Name,
                    CheckInTime = attendance.CreatedDateTime,
                    EntryTime   = attendance.StartDateTime,
                    ExitTime    = attendance.EndDateTime,
                    DidAttend   = attendance.DidAttend,
                    IsVolunteer = volunteerGroupIds.Contains(attendance.Occurrence.GroupId ?? 0),
                    Device      = attendance.Device != null ? attendance.Device.Name : "Room Scanner"
                };

                if (attendance.ForeignId != null)
                {
                    var subLocation = locationService.Get(attendance.ForeignId ?? 0);
                    if (subLocation != null)
                    {
                        record.SubLocation = subLocation.Name;
                    }
                }

                if (record.CheckInTime >= record.EntryTime && record.Device != "Room Scanner")
                {
                    record.EntryTime = null;
                }

                records.Add(record);
            }

            records = records
                      .OrderBy(r => r.CheckInTime)
                      .ToList();

            gReport.Visible    = true;
            gReport.DataSource = records;
            gReport.DataBind();
        }
示例#26
0
        /// <summary>
        /// Save RSVP response data from grid (to Attendance records).
        /// </summary>
        protected bool SaveRSVPData()
        {
            var attendees = new List <RSVPAttendee>();

            foreach (GridViewRow row in gAttendees.Rows)
            {
                if (row.RowType == DataControlRowType.DataRow)
                {
                    RockCheckBox     rcbAccept         = row.FindControl("rcbAccept") as RockCheckBox;
                    RockCheckBox     rcbDecline        = row.FindControl("rcbDecline") as RockCheckBox;
                    DataDropDownList rddlDeclineReason = row.FindControl("rddlDeclineReason") as DataDropDownList;
                    RockTextBox      tbDeclineNote     = row.FindControl("tbDeclineNote") as RockTextBox;
                    int    declineReason = int.Parse(rddlDeclineReason.SelectedValue);
                    string declineNote   = tbDeclineNote.Text;

                    attendees.Add(
                        new RSVPAttendee()
                    {
                        Accept        = rcbAccept.Checked,
                        Decline       = rcbDecline.Checked,
                        DeclineNote   = declineNote,
                        DeclineReason = declineReason,
                        PersonId      = ( int )gAttendees.DataKeys[row.RowIndex].Value
                    }
                        );
                }
            }
            using (var rockContext = new RockContext())
            {
                var occurrenceService  = new AttendanceOccurrenceService(rockContext);
                var attendanceService  = new AttendanceService(rockContext);
                var personAliasService = new PersonAliasService(rockContext);

                AttendanceOccurrence occurrence = null;

                int?groupId      = PageParameter(PageParameterKey.GroupId).AsIntegerOrNull();
                int?occurrenceId = PageParameter(PageParameterKey.OccurrenceId).AsIntegerOrNull();

                if ((occurrenceId == null) || (occurrenceId == 0))
                {
                    occurrenceId = hfNewOccurrenceId.Value.AsIntegerOrNull();
                    if ((occurrenceId == null) || (occurrenceId == 0))
                    {
                        throw new Exception("The AttendanceOccurrence does not exist.");
                    }
                }

                occurrence = occurrenceService.Get(occurrenceId.Value);

                var existingAttendees = occurrence.Attendees.ToList();

                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.StartDateTime = occurrence.Schedule != null && occurrence.Schedule.HasSchedule() ? occurrence.OccurrenceDate.Date.Add(occurrence.Schedule.StartTimeOfDay) : occurrence.OccurrenceDate;
                            occurrence.Attendees.Add(attendance);
                        }
                    }

                    if (attendance != null)
                    {
                        if (attendee.Accept)
                        {
                            var groupMember = occurrence.Group.Members.Where(gm => gm.PersonId == attendee.PersonId).FirstOrDefault();
                            if (groupMember == null)
                            {
                                groupMember             = new GroupMember();
                                groupMember.PersonId    = attendee.PersonId;
                                groupMember.GroupId     = occurrence.Group.Id;
                                groupMember.GroupRoleId = occurrence.Group.GroupType.DefaultGroupRoleId ?? 0;

                                new GroupMemberService(rockContext).Add(groupMember);
                                rockContext.SaveChanges();
                            }

                            // only set the RSVP and Date if the value is changing
                            if (attendance.RSVP != Rock.Model.RSVP.Yes)
                            {
                                attendance.RSVPDateTime = DateTime.Now;
                                attendance.RSVP         = Rock.Model.RSVP.Yes;
                            }
                            attendance.Note = string.Empty;
                            attendance.DeclineReasonValueId = null;
                        }
                        else if (attendee.Decline)
                        {
                            // only set the RSVP and Date if the value is changing
                            if (attendance.RSVP != Rock.Model.RSVP.No)
                            {
                                attendance.RSVPDateTime = DateTime.Now;
                                attendance.RSVP         = Rock.Model.RSVP.No;
                            }

                            attendance.Note = attendee.DeclineNote;
                            if (attendee.DeclineReason != 0)
                            {
                                attendance.DeclineReasonValueId = attendee.DeclineReason;
                            }
                        }
                        else
                        {
                            attendance.RSVPDateTime         = null;
                            attendance.RSVP                 = Rock.Model.RSVP.Unknown;
                            attendance.Note                 = string.Empty;
                            attendance.DeclineReasonValueId = null;
                        }
                    }
                }

                rockContext.SaveChanges();

                if (occurrence.LocationId.HasValue)
                {
                    Rock.CheckIn.KioskLocationAttendance.Remove(occurrence.LocationId.Value);
                }
            }

            return(true);
        }
        public void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap     = context.JobDetail.JobDataMap;
            var        rockContext = new RockContext();

            InteractionChannelService   channelService              = new InteractionChannelService(rockContext);
            InteractionComponentService componentService            = new InteractionComponentService(rockContext);
            InteractionService          interactionService          = new InteractionService(rockContext);
            ScheduleService             scheduleService             = new ScheduleService(rockContext);
            LocationService             locationService             = new LocationService(rockContext);
            AttendanceService           attendanceService           = new AttendanceService(rockContext);
            AttendanceOccurrenceService attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            GroupService groupService = new GroupService(rockContext);

            // Load the channel
            InteractionChannelCache channel = InteractionChannelCache.Get(dataMap.GetString("InteractionChannel").AsGuid());

            // Setup
            int    campusLocationTypeId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_CAMPUS).Id;
            var    groupType            = GroupTypeCache.Get(dataMap.GetString("GroupType").AsGuid());
            var    groupLocations       = groupService.GetByGroupTypeId(groupType.Id).Where(g => g.IsActive == true).SelectMany(g => g.GroupLocations).ToList();
            string operation            = !string.IsNullOrWhiteSpace(dataMap.GetString("Operation")) ? dataMap.GetString("Operation") : null;

            // Fetch the job so we can get the last run date/time
            int jobId      = Convert.ToInt16(context.JobDetail.Description);
            var jobService = new ServiceJobService(rockContext);
            var job        = jobService.Get(jobId);

            DateTime  lastRun = job?.LastSuccessfulRunDateTime ?? DateTime.MinValue;
            var       componentCampusMapping = dataMap.GetString("ComponentCampusMapping").AsDictionaryOrNull();
            DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||");

            // Flip the component campus mapping around and translate to ids
            Dictionary <int, List <int> > campusComponentIds = new Dictionary <int, List <int> >();

            foreach (CampusCache campus in CampusCache.All())
            {
                var componentNames = componentCampusMapping.Where(ccm => ccm.Value == campus.Name).Select(c => c.Key.ToLower());
                campusComponentIds[campus.Id] = componentService.Queryable().Where(cs => componentNames.Contains(cs.Name.ToLower()) && cs.ChannelId == channel.Id).Select(c => c.Id).ToList();
            }

            foreach (GroupLocation gl in groupLocations)
            {
                if (gl.Group.CampusId.HasValue)
                {
                    Location   location     = gl.Location;
                    List <int> componentIds = campusComponentIds[gl.Group.CampusId.Value];

                    foreach (Schedule schedule in gl.Schedules)
                    {
                        var occurrences = schedule.GetOccurrences(dateRange.Start.Value, dateRange.End.Value);
                        foreach (var occurrence in occurrences)
                        {
                            DateTime startDate = occurrence.Period.StartTime.Value;
                            DateTime endDate   = occurrence.Period.EndTime.Value;

                            var peopleAttended = interactionService.Queryable().Where(
                                i => componentIds.Contains(i.InteractionComponentId) &&
                                i.InteractionDateTime <= endDate &&
                                i.InteractionEndDateTime >= startDate &&
                                i.PersonAliasId != null &&
                                (i.CreatedDateTime > lastRun || i.PersonalDevice.ModifiedDateTime > lastRun || i.PersonalDevice.CreatedDateTime > lastRun) &&
                                (operation == null || i.Operation == operation)
                                ).Select(i => i.PersonAliasId).Distinct();
                            int newAttendance = 0;

                            var occurrenceModel = attendanceOccurrenceService.Get(occurrence.Period.StartTime.Value.Date, gl.GroupId, location.Id, schedule.Id);

                            // Make sure we don't already have an attendance Record
                            var existingAttendees = attendanceOccurrenceService.Queryable().Where(ao => DbFunctions.TruncateTime(ao.OccurrenceDate) == occurrence.Period.StartTime.Value.Date && ao.ScheduleId == schedule.Id && ao.GroupId == gl.GroupId && ao.LocationId == location.Id).SelectMany(a => a.Attendees).Where(a => a.DidAttend == true).Select(a => a.PersonAliasId);
                            foreach (int personAliasId in peopleAttended.Except(existingAttendees))
                            {
                                // Check to see if an occurrence exists already
                                if (occurrenceModel == null)
                                {
                                    var attendance = attendanceService.AddOrUpdate(personAliasId, occurrence.Period.StartTime.Value, gl.GroupId, location.Id, schedule.Id, gl.Group.CampusId);

                                    attendance.EndDateTime = occurrence.Period?.EndTime?.Value;
                                    attendance.DidAttend   = true;
                                    attendance.CampusId    = gl.Group.CampusId;
                                    occurrenceModel        = attendance.Occurrence;
                                }
                                else
                                {
                                    Attendance attendance = new Attendance();
                                    attendance.PersonAliasId = personAliasId;
                                    attendance.OccurrenceId  = occurrenceModel.Id;
                                    attendance.StartDateTime = occurrence.Period.StartTime.Value;
                                    attendance.EndDateTime   = occurrence.Period?.EndTime?.Value;
                                    attendance.DidAttend     = true;
                                    attendance.CampusId      = gl.Group.CampusId;
                                    attendanceService.Add(attendance);
                                }

                                newAttendance++;
                            }
                            if (newAttendance > 0)
                            {
                                rockContext.SaveChanges();
                                context.Result += string.Format("{0} people attended {1} on {2}.\n", newAttendance, gl.Group.Campus.Name, occurrence.Period.StartTime.Value.ToString("MM/dd/yyyy h:mm tt"));
                            }
                        }
                    }
                }
            }
        }
示例#28
0
        /// <summary>
        /// Binds the Attendance Occurrences ( Which shows the Location for the Attendance Occurrence for the selected Group + DateTime + Location ).
        /// groupScheduler.js will populate these with the scheduled resources
        /// </summary>
        private void BindAttendanceOccurrences()
        {
            var occurrenceSundayDate          = hfOccurrenceSundayDate.Value.AsDateTime().Value.Date;
            var occurrenceSundayWeekStartDate = occurrenceSundayDate.AddDays(-6);

            // make sure we don't let them schedule dates in the past
            if (occurrenceSundayWeekStartDate <= RockDateTime.Today)
            {
                occurrenceSundayWeekStartDate = RockDateTime.Today;
            }

            var scheduleId = rblSchedule.SelectedValueAsId();

            var rockContext        = new RockContext();
            var occurrenceSchedule = new ScheduleService(rockContext).GetNoTracking(scheduleId ?? 0);

            if (occurrenceSchedule == null)
            {
                btnAutoSchedule.Visible = false;
                return;
            }

            // get all the occurrences for the selected week for this scheduled (It could be more than once a week if it is a daily scheduled, or it might not be in the selected week if it is every 2 weeks, etc)
            var scheduleOccurrenceDateTimeList = occurrenceSchedule.GetScheduledStartTimes(occurrenceSundayWeekStartDate, occurrenceSundayDate.AddDays(1));

            if (!scheduleOccurrenceDateTimeList.Any())
            {
                btnAutoSchedule.Visible = false;
                return;
            }

            var occurrenceDateList = scheduleOccurrenceDateTimeList.Select(a => a.Date).ToList();

            btnAutoSchedule.Visible = true;

            var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);
            var selectedGroupLocationIds    = cblGroupLocations.SelectedValuesAsInt;

            List <AttendanceOccurrence> missingAttendanceOccurrenceList = attendanceOccurrenceService.CreateMissingAttendanceOccurrences(occurrenceDateList, scheduleId.Value, selectedGroupLocationIds);

            if (missingAttendanceOccurrenceList.Any())
            {
                attendanceOccurrenceService.AddRange(missingAttendanceOccurrenceList);
                rockContext.SaveChanges();
            }

            IQueryable <AttendanceOccurrenceService.AttendanceOccurrenceGroupLocationScheduleConfigJoinResult> attendanceOccurrenceGroupLocationScheduleConfigQuery = attendanceOccurrenceService.AttendanceOccurrenceGroupLocationScheduleConfigJoinQuery(occurrenceDateList, scheduleId.Value, selectedGroupLocationIds);

            var attendanceOccurrencesList = attendanceOccurrenceGroupLocationScheduleConfigQuery.AsNoTracking()
                                            .OrderBy(a => a.GroupLocation.Order).ThenBy(a => a.GroupLocation.Location.Name)
                                            .Select(a => new AttendanceOccurrenceRowItem
            {
                LocationName           = a.AttendanceOccurrence.Location.Name,
                GroupLocationOrder     = a.GroupLocation.Order,
                LocationId             = a.AttendanceOccurrence.LocationId,
                Schedule               = a.AttendanceOccurrence.Schedule,
                OccurrenceDate         = a.AttendanceOccurrence.OccurrenceDate,
                AttendanceOccurrenceId = a.AttendanceOccurrence.Id,
                CapacityInfo           = new CapacityInfo
                {
                    MinimumCapacity = a.GroupLocationScheduleConfig.MinimumCapacity,
                    DesiredCapacity = a.GroupLocationScheduleConfig.DesiredCapacity,
                    MaximumCapacity = a.GroupLocationScheduleConfig.MaximumCapacity
                }
            }).ToList();

            var groupId = hfGroupId.Value.AsInteger();

            var attendanceOccurrencesOrderedList = attendanceOccurrencesList.OrderBy(a => a.ScheduledDateTime).ThenBy(a => a.GroupLocationOrder).ThenBy(a => a.LocationName).ToList();

            // if there are any people that signed up with no location preference, add the to a special list of "No Location Preference" occurrences to the top of the list
            var unassignedLocationOccurrenceList = attendanceOccurrenceService.Queryable()
                                                   .Where(a => occurrenceDateList.Contains(a.OccurrenceDate) && a.ScheduleId == scheduleId.Value && a.GroupId == groupId && a.LocationId.HasValue == false)
                                                   .Where(a => a.Attendees.Any(x => x.RequestedToAttend == true || x.ScheduledToAttend == true))
                                                   .Select(a => new AttendanceOccurrenceRowItem
            {
                LocationName           = "No Location Preference",
                GroupLocationOrder     = 0,
                LocationId             = null,
                Schedule               = a.Schedule,
                OccurrenceDate         = a.OccurrenceDate,
                AttendanceOccurrenceId = a.Id,
                CapacityInfo           = new CapacityInfo()
            })
                                                   .ToList()
                                                   .OrderBy(a => a.ScheduledDateTime)
                                                   .ToList();


            attendanceOccurrencesOrderedList.InsertRange(0, unassignedLocationOccurrenceList);

            rptAttendanceOccurrences.DataSource = attendanceOccurrencesOrderedList;
            rptAttendanceOccurrences.DataBind();

            hfDisplayedOccurrenceIds.Value = attendanceOccurrencesOrderedList.Select(a => a.AttendanceOccurrenceId).ToList().AsDelimited(",");
        }
示例#29
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);
        }
示例#30
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);
            }
        }