示例#1
0
        /// <summary>
        /// Processes the selection.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="schedule">The schedule.</param>
        /// <returns></returns>
        protected bool ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
        {
            if (person != null)
            {
                string msg = string.Format(GetAttributeValue("NoOptionAfterSelectMessage"), person.Person.FullName);
                if (!ProcessSelection(
                        maWarning,
                        () => person.SelectedGroupTypes(schedule)
                        .SelectMany(t => t.SelectedGroups(schedule)
                                    .SelectMany(g => g.SelectedLocations(schedule)
                                                .SelectMany(l => l.ValidSchedules(schedule))))
                        .Count() <= 0,
                        string.Format("<p>{0}</p>", msg),
                        CurrentCheckInState.CheckInType.TypeOfCheckin == TypeOfCheckin.Family))
                {
                    ClearSelection();
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
 /// <summary>
 /// Toggles on or off one check-in GroupLocationSchedule (it will deselct others)
 /// </summary>
 /// <param name="chGroup">Checkin Group</param>
 /// <param name="chLocation">Checkin Location</param>
 /// <param name="chSchedule">Checkin Schedule</param>
 /// <param name="alreadySelected">Is the Group Location Schedule already selected</param>
 private void ToggleClass(CheckInGroup chGroup, CheckInLocation chLocation, CheckInSchedule chSchedule, bool alreadySelected)
 {
     foreach (var groupType in CurrentCheckInState.CheckIn.CurrentPerson.GroupTypes)
     {
         groupType.Selected = true;
         foreach (var group in groupType.Groups)
         {
             group.Selected = false;
             foreach (var location in group.Locations)
             {
                 location.Selected = false;
                 foreach (var schedule in location.Schedules)
                 {
                     schedule.Selected = false;
                 }
             }
         }
     }
     if (!alreadySelected)
     {
         chGroup.Selected    = true;
         chLocation.Selected = true;
         chSchedule.Selected = true;
         btnCheckin.Visible  = true;
     }
     SaveState();
     ShowPersonCheckin();
 }
示例#3
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)
            {
                var groupService = new GroupService(rockContext);

                foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected).ToList())
                {
                    foreach (var person in family.People)
                    {
                        var checkinGroupTypes = new List <CheckInGroupType>();

                        foreach (var id in checkInState.ConfiguredGroupTypes)
                        {
                            var cgt = new CheckInGroupType();
                            cgt.GroupType = GroupTypeCache.Get(id);
                            checkinGroupTypes.Add(cgt);
                            var groups = groupService.Queryable().Where(g => g.GroupTypeId == id);
                            List <CheckInGroup> checkinGroups = new List <CheckInGroup>();
                            foreach (var group in groups)
                            {
                                var cg = new CheckInGroup();
                                cg.Group = group;
                                group.LoadAttributes();
                                checkinGroups.Add(cg);
                                var groupLocations = group.GroupLocations;
                                List <CheckInLocation> checkinLocations = new List <CheckInLocation>();
                                foreach (var groupLocation in groupLocations)
                                {
                                    var cl = new CheckInLocation();
                                    cl.Location = groupLocation.Location;
                                    checkinLocations.Add(cl);
                                    var schedules = new List <CheckInSchedule>();
                                    foreach (var schedule in groupLocation.Schedules.ToList())
                                    {
                                        if (!schedule.WasCheckInActive(RockDateTime.Now))
                                        {
                                            continue;
                                        }
                                        var cs = new CheckInSchedule();
                                        cs.Schedule = schedule;
                                        schedules.Add(cs);
                                    }
                                    cl.Schedules = schedules;
                                }
                                cg.Locations = checkinLocations;
                            }
                            cgt.Groups = checkinGroups;
                        }
                        person.GroupTypes = checkinGroupTypes;
                    }
                }
                return(true);
            }
            errorMessages.Add($"Attempted to run {this.GetType().GetFriendlyTypeName()} in check-in, but the check-in state was null.");
            return(false);
        }
        /// <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, Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState != null)
            {
                bool loadAll = false;
                if (bool.TryParse(GetAttributeValue(action, "LoadAll"), out loadAll) && loadAll)
                {
                    loadAll = true;
                }

                foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected).ToList())
                {
                    foreach (var person in family.People.Where(p => p.Selected).ToList())
                    {
                        foreach (var groupType in person.GroupTypes.Where(g => g.Selected || loadAll).ToList())
                        {
                            var kioskGroupType = checkInState.Kiosk.FilteredGroupTypes(checkInState.ConfiguredGroupTypes).Where(g => g.GroupType.Id == groupType.GroupType.Id).FirstOrDefault();
                            if (kioskGroupType != null)
                            {
                                foreach (var group in groupType.Groups.Where(g => g.Selected || loadAll).ToList())
                                {
                                    foreach (var location in group.Locations.Where(l => l.Selected || loadAll).ToList())
                                    {
                                        var kioskGroup = kioskGroupType.KioskGroups.Where(g => g.Group.Id == group.Group.Id).FirstOrDefault();
                                        if (kioskGroup != null)
                                        {
                                            var kioskLocation = kioskGroup.KioskLocations.Where(l => l.Location.Id == location.Location.Id).FirstOrDefault();
                                            if (kioskLocation != null)
                                            {
                                                foreach (var kioskSchedule in kioskLocation.KioskSchedules)
                                                {
                                                    if (!location.Schedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id))
                                                    {
                                                        var checkInSchedule = new CheckInSchedule();
                                                        checkInSchedule.Schedule  = kioskSchedule.Schedule.Clone(false);
                                                        checkInSchedule.StartTime = kioskSchedule.StartTime;
                                                        location.Schedules.Add(checkInSchedule);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
示例#5
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)
            {
                var groupService = new GroupService(rockContext);

                foreach (var family in checkInState.CheckIn.Families.Where(f => f.Selected).ToList())
                {
                    foreach (var person in family.People)
                    {
                        var checkinGroupTypes = new List <CheckInGroupType>();

                        foreach (var id in checkInState.ConfiguredGroupTypes)
                        {
                            var cgt = new CheckInGroupType();
                            cgt.GroupType = GroupTypeCache.Get(id);
                            checkinGroupTypes.Add(cgt);
                            var groups = groupService.Queryable().Where(g => g.GroupTypeId == id);
                            List <CheckInGroup> checkinGroups = new List <CheckInGroup>();
                            foreach (var group in groups.Where(g => g.IsActive))
                            {
                                var cg = new CheckInGroup();
                                cg.Group = group;
                                group.LoadAttributes();
                                checkinGroups.Add(cg);
                                var groupLocations = group.GroupLocations;
                                List <CheckInLocation> checkinLocations = new List <CheckInLocation>();
                                foreach (var groupLocation in groupLocations)
                                {
                                    var cl = new CheckInLocation();
                                    cl.Location = groupLocation.Location;
                                    cl.CampusId = cl.Location.CampusId;
                                    checkinLocations.Add(cl);
                                    var schedules = new List <CheckInSchedule>();
                                    foreach (var schedule in groupLocation.Schedules)
                                    {
                                        var cs = new CheckInSchedule();
                                        cs.Schedule = schedule;
                                        schedules.Add(cs);
                                    }
                                    cl.Schedules = schedules;
                                }
                                cg.Locations = checkinLocations;
                            }
                            cgt.Groups = checkinGroups;
                        }
                        person.GroupTypes = checkinGroupTypes;
                    }
                }
                return(true);
            }
            return(false);
        }
 protected void ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
 {
     if (person != null)
     {
         if (!ProcessSelection(
                 maWarning,
                 () => person.SelectedGroupTypes(schedule)
                 .SelectMany(t => t.Groups.Where(g => !g.ExcludedByFilter))
                 .Count() <= 0,
                 "<p>Sorry, based on your selection, there are currently not any available locations that can be checked into.</p>"))
         {
             ClearSelection();
         }
     }
 }
 protected void ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
 {
     if (person != null)
     {
         if (!ProcessSelection(
                 maWarning,
                 () => person.SelectedGroupTypes(schedule)
                 .SelectMany(t => t.SelectedGroups(schedule)
                             .SelectMany(g => g.SelectedLocations(schedule)
                                         .SelectMany(l => l.ValidSchedules(schedule))))
                 .Count() <= 0,
                 "<p>Sorry, based on your selection, there are currently not any available times that can be checked into.</p>"))
         {
             ClearSelection();
         }
     }
 }
示例#8
0
        public void CheckInStatusStatus(int idSt, int st)
        {
            CheckInStatus newStatus = new CheckInStatus();

            newStatus.FlightNumber = idSt;
            if (st == 2)
            {
                newStatus.Status = CheckIn_Status.Finish;
                Console.WriteLine("9: Check in on flight number {0} is over", idSt);
            }
            else
            {
                newStatus.Status = CheckIn_Status.Start;
                Console.WriteLine("9: Check in on flight number {0}  has begun", idSt);
            }
            CheckInSchedule.getInstance().ChangeStatus(newStatus);
            Console.WriteLine("9:  flight status changeg");
        }
示例#9
0
        /// <summary>
        /// Handles the Delete event of the gPersonList 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 gPersonList_Delete(object sender, RowEventArgs e)
        {
            var dataKeyValues = gPersonList.DataKeys[e.RowIndex].Values;
            var personId      = Convert.ToInt32(dataKeyValues["PersonId"]);
            var locationId    = Convert.ToInt32(dataKeyValues["LocationId"]);
            var scheduleId    = Convert.ToInt32(dataKeyValues["ScheduleId"]);

            var selectedPerson = CurrentCheckInState.CheckIn.Families.Where(f => f.Selected).FirstOrDefault()
                                 .People.Where(p => p.Person.Id == personId).FirstOrDefault();
            var selectedGroups = selectedPerson.GroupTypes.Where(gt => gt.Selected)
                                 .SelectMany(gt => gt.Groups.Where(g => g.Selected));
            CheckInGroup selectedGroup = selectedGroups.Where(g => g.Selected &&
                                                              g.Locations.Any(l => l.Location.Id == locationId &&
                                                                              l.Schedules.Any(s => s.Schedule.Id == scheduleId))).FirstOrDefault();
            CheckInLocation selectedLocation = selectedGroup.Locations.Where(l => l.Selected &&
                                                                             l.Location.Id == locationId &&
                                                                             l.Schedules.Any(s => s.Schedule.Id == scheduleId)).FirstOrDefault();
            CheckInSchedule selectedSchedule = selectedLocation.Schedules.Where(s => s.Selected &&
                                                                                s.Schedule.Id == scheduleId).FirstOrDefault();

            selectedSchedule.Selected    = false;
            selectedSchedule.PreSelected = false;

            // clear checkin rows without anything selected
            if (!selectedLocation.Schedules.Any(s => s.Selected))
            {
                selectedLocation.Selected    = false;
                selectedLocation.PreSelected = false;
            }

            if (!selectedGroup.Locations.Any(l => l.Selected))
            {
                selectedGroup.Selected    = false;
                selectedGroup.PreSelected = false;
            }

            if (!selectedGroups.Any())
            {
                selectedPerson.Selected    = false;
                selectedPerson.PreSelected = false;
            }

            BindGrid();
        }
        /// <summary>
        /// Processes the selection.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="schedule">The schedule.</param>
        /// <returns></returns>
        protected bool ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
        {
            if (person != null)
            {
                if (!ProcessSelection(
                        maWarning,
                        () => person.SelectedGroupTypes(schedule)
                        .SelectMany(t => t.Groups.Where(g => !g.ExcludedByFilter))
                        .Count() <= 0,
                        string.Format("<p>Sorry, based on your selection, there are currently not any available locations that {0} can check into.</p>", person.Person.NickName),
                        true))
                {
                    ClearSelection();
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
示例#11
0
        /// <summary>
        /// Processes the selection.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="schedule">The schedule.</param>
        /// <returns></returns>
        protected bool ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
        {
            if (person != null)
            {
                string msg = string.Format(GetAttributeValue(AttributeKey.NoOptionAfterSelectMessage), person.Person.NickName);
                if (!ProcessSelection(
                        maWarning,
                        () => person.SelectedGroupTypes(schedule)
                        .SelectMany(t => t.Groups.Where(g => !g.ExcludedByFilter))
                        .Count() <= 0,
                        string.Format("<p>{0}</p>", msg),
                        true))
                {
                    ClearSelection();
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
示例#12
0
        /// <summary>
        /// Processes the selection.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="schedule">The schedule.</param>
        /// <returns></returns>
        protected bool ProcessSelection(CheckInPerson person, CheckInSchedule schedule)
        {
            if (person != null)
            {
                if (!ProcessSelection(
                        maWarning,
                        () => person.SelectedGroupTypes(schedule)
                        .SelectMany(t => t.SelectedGroups(schedule)
                                    .SelectMany(g => g.SelectedLocations(schedule)
                                                .SelectMany(l => l.ValidSchedules(schedule))))
                        .Count() <= 0,
                        string.Format("<p>Sorry, based on your selection, there are currently not any available times that {0} can check into.</p>", person.Person.FullName),
                        CurrentCheckInState.CheckInType.TypeOfCheckin == TypeOfCheckin.Family))
                {
                    ClearSelection();
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
示例#13
0
        public ActionResult PostPassenger([FromBody] Passenger passenger)
        {
            int r = CheckInSchedule.getInstance().find(passenger.Ticket.fID);

            if (r == 0)
            {
                Console.WriteLine("9:  flight number {0} not found", passenger.Ticket.fID);
                return(NotFound());
            }
            else
            {
                HttpClient httpClient = new HttpClient();
                httpClient.BaseAddress = new Uri("https://localhost:44304/");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = httpClient.GetAsync("get/" + passenger.Ticket.pID).Result;

                if (response.IsSuccessStatusCode)
                {
                    HttpContent responseContent = response.Content;
                    var         json            = responseContent.ReadAsStringAsync().Result;
                    var         rs = JsonConvert.DeserializeObject <string>(json);

                    int f = 0;
                    if (rs != "0")
                    {
                        if (passenger.BaggageWeight <= 25)
                        {
                            Baggage baggage = new Baggage();
                            baggage.FlightNumber  = passenger.Ticket.fID;
                            baggage.PassengerId   = passenger.Ticket.pID;
                            baggage.BaggageWeight = passenger.BaggageWeight;
                            BaggageList.Add(baggage);

                            foreach (var i in FoodList)
                            {
                                if (passenger.Ticket.fID == i.FlightNumber)
                                {
                                    f = 1;
                                    if (passenger.TypeOfFood == TypeOfFood.Normal)
                                    {
                                        i.Normal++;
                                    }
                                    else
                                    {
                                        i.Vegan++;
                                    }
                                }
                            }
                            if (f == 0)
                            {
                                Food food = new Food();
                                food.FlightNumber = passenger.Ticket.fID;
                                if (passenger.TypeOfFood == TypeOfFood.Normal)
                                {
                                    food.Normal++;
                                }
                                else
                                {
                                    food.Vegan++;
                                }
                                FoodList.Add(food);
                            }

                            Console.WriteLine("9: passenger number {0} is registered for flight number {1} ", passenger.Ticket.pID, passenger.Ticket.fID);
                            return(NoContent());
                        }
                        else
                        {
                            Console.WriteLine("9: baggage overweight");
                            return(StatusCode(403)); //перевес багажа
                        }
                    }
                    else
                    {
                        Console.WriteLine("9: passenger {0} : ticket not found ", passenger.Ticket.pID);
                        return(NotFound());
                    }
                }
                else
                {
                    Console.WriteLine("9: passenger {0} : ticket not found ", passenger.Ticket.pID);
                    return(NotFound());
                }
            }
        }
示例#14
0
        /// <summary>
        /// Enforces the strict location threshold by removing attendances that would have ended up going into full location+schedules.
        /// Note: The is also checked earlier in the check-in process, so this catches ones that might have just gotten full in the last few seconds.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <param name="checkInState">State of the check in.</param>
        /// <param name="attendanceService">The attendance service.</param>
        /// <param name="currentOccurrences">The current occurrences.</param>
        /// <param name="person">The person.</param>
        /// <param name="group">The group.</param>
        /// <param name="location">The location.</param>
        /// <param name="schedule">The schedule.</param>
        /// <param name="startDateTime">The start date time.</param>
        private void EnforceStrictLocationThreshold(WorkflowAction action, CheckInState checkInState, AttendanceService attendanceService, List <OccurrenceRecord> currentOccurrences, CheckInPerson person, CheckInGroup group, CheckInLocation location, CheckInSchedule schedule, DateTime startDateTime)
        {
            var thresHold = location.Location.SoftRoomThreshold.Value;

            if (checkInState.ManagerLoggedIn && location.Location.FirmRoomThreshold.HasValue && location.Location.FirmRoomThreshold.Value > location.Location.SoftRoomThreshold.Value)
            {
                thresHold = location.Location.FirmRoomThreshold.Value;
            }

            var currentOccurrence = GetCurrentOccurrence(currentOccurrences, location, schedule, startDateTime.Date);

            // The totalAttended is the number of people still checked in (not people who have been checked-out)
            // not counting the current person who may already be checked in,
            // + the number of people we have checked in so far (but haven't been saved yet).
            var attendanceQry = attendanceService.GetByDateOnLocationAndSchedule(startDateTime.Date, location.Location.Id, schedule.Schedule.Id)
                                .AsNoTracking()
                                .Where(a => a.EndDateTime == null);

            // Only process if the current person is NOT already checked-in to this location and schedule
            if (!attendanceQry.Where(a => a.PersonAlias.PersonId == person.Person.Id).Any())
            {
                var totalAttended = attendanceQry.Count() + (currentOccurrence == null ? 0 : currentOccurrence.Count);

                // If over capacity, remove the schedule and add a warning message.
                if (totalAttended >= thresHold)
                {
                    // Remove the schedule since the location was full for this schedule.
                    location.Schedules.Remove(schedule);

                    var message = new CheckInMessage()
                    {
                        MessageType = MessageType.Warning
                    };

                    var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null);
                    mergeFields.Add(MergeFieldKey.Person, person.Person);
                    mergeFields.Add(MergeFieldKey.Group, group.Group);
                    mergeFields.Add(MergeFieldKey.Location, location.Location);
                    mergeFields.Add(MergeFieldKey.Schedule, schedule.Schedule);
                    message.MessageText = GetAttributeValue(action, AttributeKey.NotCheckedInMessageFormat).ResolveMergeFields(mergeFields);

                    // Now add it to the check-in state message list for others to see.
                    checkInState.Messages.Add(message);
                    return;
                }
                else
                {
                    // Keep track of anyone who was checked in so far.
                    if (currentOccurrence == null)
                    {
                        currentOccurrence = new OccurrenceRecord()
                        {
                            Date       = startDateTime.Date,
                            LocationId = location.Location.Id,
                            ScheduleId = schedule.Schedule.Id
                        };

                        currentOccurrences.Add(currentOccurrence);
                    }

                    currentOccurrence.Count += 1;
                }
            }
        }
示例#15
0
 /// <summary>
 /// Gets the current occurrence from the given list for the matching location, schedule and startDateTime.
 /// </summary>
 /// <param name="currentOccurrences">The current occurrences.</param>
 /// <param name="location">The location.</param>
 /// <param name="schedule">The schedule.</param>
 /// <param name="startDateTime">The start date time.</param>
 /// <returns></returns>
 private OccurrenceRecord GetCurrentOccurrence(List <OccurrenceRecord> currentOccurrences, CheckInLocation location, CheckInSchedule schedule, DateTime startDateTime)
 {
     return(currentOccurrences
            .Where(a =>
                   a.Date == startDateTime.Date &&
                   a.LocationId == location.Location.Id &&
                   a.ScheduleId == schedule.Schedule.Id)
            .FirstOrDefault());
 }
示例#16
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, Rock.Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState == null)
            {
                return(false);
            }

            int  peopleWithoutAssignments = 0;
            bool roomBalance          = GetAttributeValue(action, "RoomBalance").AsBoolean();
            int  balanceOverride      = GetAttributeValue(action, "DifferentialOverride").AsIntegerOrNull() ?? 10;
            int  previousMonthsNumber = GetAttributeValue(action, "PreviousMonthsAttendance").AsIntegerOrNull() ?? 3;
            int  maxAssignments       = GetAttributeValue(action, "MaxAssignments").AsIntegerOrNull() ?? 5;

            var cutoffDate        = Rock.RockDateTime.Today.AddMonths(previousMonthsNumber * -1);
            var attendanceService = new AttendanceService(rockContext);

            var family = checkInState.CheckIn.Families.FirstOrDefault(f => f.Selected);

            if (family != null)
            {
                // get the number of people checking in, including visitors or first-timers
                peopleWithoutAssignments = family.People.Where(p => p.Selected).Count();

                foreach (var previousAttender in family.People.Where(p => p.Selected && !p.FirstTime))
                {
                    var personGroupTypeIds = previousAttender.GroupTypes.Select(gt => gt.GroupType.Id);

                    var lastDateAttendances = attendanceService.Queryable()
                                              .Where(a =>
                                                     a.PersonAlias.PersonId == previousAttender.Person.Id &&
                                                     personGroupTypeIds.Contains(a.Group.GroupTypeId) &&
                                                     a.StartDateTime >= cutoffDate && a.DidAttend == true)
                                              .OrderByDescending(a => a.StartDateTime).Take(maxAssignments)
                                              .ToList();

                    if (lastDateAttendances.Any())
                    {
                        bool createdMatchingAssignment = false;
                        var  isSpecialNeeds            = previousAttender.Person.GetAttributeValue("IsSpecialNeeds").AsBoolean();

                        var lastAttended = lastDateAttendances.Max(a => a.StartDateTime).Date;
                        foreach (var groupAttendance in lastDateAttendances.Where(a => a.StartDateTime >= lastAttended))
                        {
                            // Start with filtered groups unless they have abnormal age and grade parameters (1%)
                            var groupType = previousAttender.GroupTypes.FirstOrDefault(gt => gt.GroupType.Id == groupAttendance.Group.GroupTypeId && (!gt.ExcludedByFilter || isSpecialNeeds));
                            if (groupType != null)
                            {
                                CheckInGroup group = null;
                                if (groupType.Groups.Count == 1)
                                {
                                    // Only a single group is open
                                    group = groupType.Groups.FirstOrDefault(g => !g.ExcludedByFilter || isSpecialNeeds);
                                }
                                else
                                {
                                    // Pick the group they last attended
                                    group = groupType.Groups.FirstOrDefault(g => g.Group.Id == groupAttendance.GroupId && (!g.ExcludedByFilter || isSpecialNeeds));

                                    if (group != null && roomBalance && !isSpecialNeeds)
                                    {
                                        var currentAttendance   = group.Locations.Select(l => KioskLocationAttendance.Read(l.Location.Id).CurrentCount).Sum();
                                        var lowestAttendedGroup = groupType.Groups.Where(g => !g.ExcludedByFilter)
                                                                  .Select(g => new { Group = g, Attendance = g.Locations.Select(l => KioskLocationAttendance.Read(l.Location.Id).CurrentCount).Sum() })
                                                                  .OrderBy(g => g.Attendance)
                                                                  .FirstOrDefault();

                                        if (lowestAttendedGroup != null && lowestAttendedGroup.Attendance < (currentAttendance - balanceOverride))
                                        {
                                            group = lowestAttendedGroup.Group;
                                        }
                                    }
                                }

                                if (group != null)
                                {
                                    CheckInLocation location = null;
                                    if (group.Locations.Count == 1)
                                    {
                                        // Only a single location is open
                                        location = group.Locations.FirstOrDefault(l => !l.ExcludedByFilter || isSpecialNeeds);
                                    }
                                    else
                                    {
                                        // Pick the location they last attended
                                        location = group.Locations.FirstOrDefault(l => l.Location.Id == groupAttendance.LocationId && (!l.ExcludedByFilter || isSpecialNeeds));

                                        if (location != null && roomBalance && !isSpecialNeeds)
                                        {
                                            var currentAttendance      = KioskLocationAttendance.Read(location.Location.Id).CurrentCount;
                                            var lowestAttendedLocation = group.Locations.Where(l => !l.ExcludedByFilter)
                                                                         .Select(l => new { Location = l, Attendance = KioskLocationAttendance.Read(location.Location.Id).CurrentCount })
                                                                         .OrderBy(l => l.Attendance)
                                                                         .FirstOrDefault();

                                            if (lowestAttendedLocation != null && lowestAttendedLocation.Attendance < (currentAttendance - balanceOverride))
                                            {
                                                location = lowestAttendedLocation.Location;
                                            }
                                        }
                                    }

                                    if (location != null)
                                    {
                                        CheckInSchedule schedule = null;
                                        if (location.Schedules.Count == 1)
                                        {
                                            schedule = location.Schedules.FirstOrDefault(s => !s.ExcludedByFilter || isSpecialNeeds);
                                        }
                                        else if (groupAttendance.ScheduleId != null)
                                        {
                                            schedule = location.Schedules.FirstOrDefault(s => s.Schedule.Id == groupAttendance.ScheduleId && (!s.ExcludedByFilter || isSpecialNeeds));
                                        }
                                        else
                                        {
                                            // if the schedule doesn't exactly match but everything else does, select it
                                            schedule = location.Schedules.FirstOrDefault(s => (!s.ExcludedByFilter && !isSpecialNeeds));
                                        }

                                        if (schedule != null)
                                        {
                                            schedule.Selected            = true;
                                            schedule.PreSelected         = true;
                                            schedule.LastCheckIn         = groupAttendance.StartDateTime;
                                            location.Selected            = true;
                                            location.PreSelected         = true;
                                            location.LastCheckIn         = groupAttendance.StartDateTime;
                                            group.Selected               = true;
                                            group.PreSelected            = true;
                                            group.LastCheckIn            = groupAttendance.StartDateTime;
                                            groupType.Selected           = true;
                                            groupType.PreSelected        = true;
                                            group.LastCheckIn            = groupAttendance.StartDateTime;
                                            groupType.LastCheckIn        = groupAttendance.StartDateTime;
                                            groupType.Selected           = true;
                                            groupType.PreSelected        = true;
                                            previousAttender.PreSelected = true;
                                            previousAttender.LastCheckIn = groupAttendance.StartDateTime;
                                            createdMatchingAssignment    = true;
                                        }
                                    }
                                }
                            }
                        }

                        if (createdMatchingAssignment)
                        {
                            peopleWithoutAssignments--;
                        }
                    }
                }
            }

            // true condition will continue to the next auto-assignment
            // false condition will stop processing auto-assignments
            if (action.Activity.AttributeValues.Any() && action.Activity.AttributeValues.ContainsKey("ContinueAssignments"))
            {
                var continueAssignments = peopleWithoutAssignments > 0;
                action.Activity.AttributeValues["ContinueAssignments"].Value = continueAssignments.ToString();
            }

            return(true);
        }
示例#17
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, Model.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(true))
                    {
                        foreach (var groupType in person.GetGroupTypes(!loadAll))
                        {
                            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))
                                {
                                    foreach (var location in group.GetLocations(!loadAll))
                                    {
                                        var kioskGroup = kioskGroupType.KioskGroups
                                                         .Where(g => g.Group.Id == group.Group.Id && g.IsCheckInActive)
                                                         .FirstOrDefault();

                                        if (kioskGroup != null)
                                        {
                                            var kioskLocation = kioskGroup.KioskLocations
                                                                .Where(l => l.Location.Id == location.Location.Id && l.IsCheckInActive)
                                                                .FirstOrDefault();

                                            if (kioskLocation != null)
                                            {
                                                foreach (var kioskSchedule in kioskLocation.KioskSchedules.Where(s => s.IsCheckInActive))
                                                {
                                                    if (!location.Schedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id))
                                                    {
                                                        var checkInSchedule = new CheckInSchedule();
                                                        checkInSchedule.Schedule  = kioskSchedule.Schedule.Clone(false);
                                                        checkInSchedule.StartTime = kioskSchedule.StartTime;
                                                        location.Schedules.Add(checkInSchedule);
                                                    }

                                                    if (checkInState.CheckInType != null &&
                                                        checkInState.CheckInType.TypeOfCheckin == TypeOfCheckin.Family &&
                                                        !person.PossibleSchedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id))
                                                    {
                                                        var checkInSchedule = new CheckInSchedule();
                                                        checkInSchedule.Schedule  = kioskSchedule.Schedule.Clone(false);
                                                        checkInSchedule.StartTime = kioskSchedule.StartTime;
                                                        person.PossibleSchedules.Add(checkInSchedule);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
        /// <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, Rock.Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState == null)
            {
                return(false);
            }

            int selectFromDaysBack    = checkInState.CheckInType.AutoSelectDaysBack;
            var roomBalanceGroupTypes = GetAttributeValue(action, "RoomBalanceGrouptypes").SplitDelimitedValues().AsGuidList();
            int roomBalanceOverride   = GetAttributeValue(action, "BalancingOverride").AsIntegerOrNull() ?? 5;
            int maxAssignments        = GetAttributeValue(action, "MaxAssignments").AsIntegerOrNull() ?? 5;
            var excludedLocations     = GetAttributeValue(action, "ExcludedLocations").SplitDelimitedValues(whitespace: false)
                                        .Select(s => s.Trim()).ToList();

            var personSpecialNeedsKey  = string.Empty;
            var personSpecialNeedsGuid = GetAttributeValue(action, "PersonSpecialNeedsAttribute").AsGuid();

            if (personSpecialNeedsGuid != Guid.Empty)
            {
                personSpecialNeedsKey = AttributeCache.Read(personSpecialNeedsGuid, rockContext).Key;
            }

            // log a warning if the attribute is missing or invalid
            if (string.IsNullOrWhiteSpace(personSpecialNeedsKey))
            {
                action.AddLogEntry(string.Format("The Person Special Needs attribute is not selected or invalid for '{0}'.", action.ActionType.Name));
            }

            var family = checkInState.CheckIn.Families.FirstOrDefault(f => f.Selected);

            if (family != null)
            {
                var cutoffDate        = RockDateTime.Today.AddDays(selectFromDaysBack * -1);
                var attendanceService = new AttendanceService(rockContext);

                // only process people who have been here before
                foreach (var previousAttender in family.People.Where(p => p.Selected && !p.FirstTime))
                {
                    // get a list of this person's available grouptypes
                    var availableGroupTypeIds = previousAttender.GroupTypes.Select(gt => gt.GroupType.Id).ToList();

                    // order by most recent attendance
                    var lastDateAttendances = attendanceService.Queryable().Where(a =>
                                                                                  a.PersonAlias.PersonId == previousAttender.Person.Id &&
                                                                                  availableGroupTypeIds.Contains(a.Group.GroupTypeId) &&
                                                                                  a.StartDateTime >= cutoffDate && a.DidAttend == true)
                                              .OrderByDescending(a => a.StartDateTime).Take(maxAssignments)
                                              .ToList();

                    if (lastDateAttendances.Any())
                    {
                        var assignmentsGiven = 0;
                        // get the most recent day, then create assignments starting with the earliest attendance record
                        var lastAttended   = lastDateAttendances.Max(a => a.StartDateTime).Date;
                        var numAttendances = lastDateAttendances.Count(a => a.StartDateTime >= lastAttended);
                        foreach (var groupAttendance in lastDateAttendances.Where(a => a.StartDateTime >= lastAttended).OrderBy(a => a.Schedule.StartTimeOfDay))
                        {
                            bool currentlyCheckedIn = false;
                            var  serviceCutoff      = groupAttendance.StartDateTime;
                            if (serviceCutoff > RockDateTime.Now.Date && groupAttendance.Schedule != null)
                            {
                                // calculate the service window to determine if people are still checked in
                                var serviceTime  = groupAttendance.StartDateTime.Date + groupAttendance.Schedule.StartTimeOfDay;
                                var serviceStart = serviceTime.AddMinutes((groupAttendance.Schedule.CheckInStartOffsetMinutes ?? 0) * -1.0);
                                serviceCutoff      = serviceTime.AddMinutes((groupAttendance.Schedule.CheckInEndOffsetMinutes ?? 0));
                                currentlyCheckedIn = RockDateTime.Now > serviceStart && RockDateTime.Now < serviceCutoff;
                            }

                            // override exists in case they are currently checked in or have special needs
                            bool useCheckinOverride = currentlyCheckedIn || previousAttender.Person.GetAttributeValue(personSpecialNeedsKey).AsBoolean();

                            // get a list of room balanced grouptype ID's since CheckInGroup model is a shallow clone
                            var roomBalanceGroupTypeIds = previousAttender.GroupTypes.Where(gt => roomBalanceGroupTypes.Contains(gt.GroupType.Guid))
                                                          .Select(gt => gt.GroupType.Id).ToList();

                            // start with filtered groups unless they have abnormal age and grade parameters (1%)
                            var groupType = previousAttender.GroupTypes.FirstOrDefault(gt => gt.GroupType.Id == groupAttendance.Group.GroupTypeId && (!gt.ExcludedByFilter || useCheckinOverride));
                            if (groupType != null)
                            {
                                // assigning the right schedule depends on prior attendance & currently available schedules being sorted
                                var orderedSchedules = groupType.Groups.SelectMany(g => g.Locations.SelectMany(l => l.Schedules))
                                                       .DistinctBy(s => s.Schedule.Id).OrderBy(s => s.Schedule.StartTimeOfDay)
                                                       .Select(s => s.Schedule.Id).ToList();

                                int?currentScheduleId = null;
                                if (orderedSchedules.Count == 1)
                                {
                                    currentScheduleId = orderedSchedules.FirstOrDefault();
                                }
                                else if (currentlyCheckedIn)
                                {
                                    // always pick the schedule they're currently checked into
                                    currentScheduleId = orderedSchedules.Where(s => s == groupAttendance.ScheduleId).FirstOrDefault();
                                }
                                else
                                {
                                    // sort the earliest schedule for the current grouptype, then skip the number of assignments already given (multiple services)
                                    currentScheduleId = groupType.AvailableForSchedule
                                                        .OrderBy(d => orderedSchedules.IndexOf(d))
                                                        .Skip(assignmentsGiven).FirstOrDefault();
                                }

                                CheckInGroup group = null;
                                if (groupType.Groups.Count == 1)
                                {
                                    // only a single group is open
                                    group = groupType.Groups.FirstOrDefault(g => !g.ExcludedByFilter || useCheckinOverride);
                                }
                                else
                                {
                                    // pick the group they last attended, as long as it's open or what they're currently checked into
                                    group = groupType.Groups.FirstOrDefault(g => g.Group.Id == groupAttendance.GroupId && (!g.ExcludedByFilter || useCheckinOverride));

                                    // room balance only on new check-ins and only for the current service
                                    if (group != null && currentScheduleId != null && roomBalanceGroupTypeIds.Contains(group.Group.GroupTypeId) && !excludedLocations.Contains(group.Group.Name) && !useCheckinOverride)
                                    {
                                        // make sure balanced rooms are open for the current service
                                        var currentAttendance = group.Locations.Where(l => l.AvailableForSchedule.Contains((int)currentScheduleId))
                                                                .Select(l => Helpers.ReadAttendanceBySchedule(l.Location.Id, currentScheduleId)).Sum();

                                        var lowestAttendedGroup = groupType.Groups.Where(g => g.AvailableForSchedule.Contains((int)currentScheduleId))
                                                                  .Where(g => !g.ExcludedByFilter && !excludedLocations.Contains(g.Group.Name))
                                                                  .Select(g => new { Group = g, Attendance = g.Locations.Select(l => Helpers.ReadAttendanceBySchedule(l.Location.Id, currentScheduleId)).Sum() })
                                                                  .OrderBy(g => g.Attendance)
                                                                  .FirstOrDefault();

                                        if (lowestAttendedGroup != null && lowestAttendedGroup.Attendance < (currentAttendance - roomBalanceOverride + 1))
                                        {
                                            group = lowestAttendedGroup.Group;
                                        }
                                    }
                                }

                                if (group != null)
                                {
                                    CheckInLocation location = null;
                                    if (group.Locations.Count == 1)
                                    {
                                        // only a single location is open
                                        location = group.Locations.FirstOrDefault(l => !l.ExcludedByFilter || useCheckinOverride);
                                    }
                                    else
                                    {
                                        // pick the location they last attended, as long as it's open or what they're currently checked into
                                        location = group.Locations.FirstOrDefault(l => l.Location.Id == groupAttendance.LocationId && (!l.ExcludedByFilter || useCheckinOverride));

                                        // room balance only on new check-ins and only for the current service
                                        if (location != null && currentScheduleId != null && roomBalanceGroupTypeIds.Contains(group.Group.GroupTypeId) && !excludedLocations.Contains(location.Location.Name) && !useCheckinOverride)
                                        {
                                            var currentAttendance = Helpers.ReadAttendanceBySchedule(location.Location.Id, currentScheduleId);

                                            var lowestAttendedLocation = group.Locations.Where(l => l.AvailableForSchedule.Contains((int)currentScheduleId))
                                                                         .Where(l => !l.ExcludedByFilter && !excludedLocations.Contains(l.Location.Name))
                                                                         .Select(l => new { Location = l, Attendance = Helpers.ReadAttendanceBySchedule(l.Location.Id, currentScheduleId) })
                                                                         .OrderBy(l => l.Attendance)
                                                                         .FirstOrDefault();

                                            if (lowestAttendedLocation != null && lowestAttendedLocation.Attendance < (currentAttendance - roomBalanceOverride + 1))
                                            {
                                                location = lowestAttendedLocation.Location;
                                            }
                                        }
                                    }

                                    if (location != null)
                                    {
                                        // the current schedule could exist on multiple locations, so pick the one owned by this location
                                        // if the current schedule just closed, get the first available schedule at this location
                                        CheckInSchedule schedule = location.Schedules.OrderByDescending(s => s.Schedule.Id == currentScheduleId).FirstOrDefault();
                                        if (schedule != null)
                                        {
                                            // it's impossible to currently be checked in unless these match exactly
                                            if (group.Group.Id == groupAttendance.GroupId && location.Location.Id == groupAttendance.LocationId && schedule.Schedule.Id == groupAttendance.ScheduleId)
                                            {
                                                // checkout feature either removes the attendance or sets the EndDateTime
                                                var endOfCheckinWindow = groupAttendance.EndDateTime ?? serviceCutoff;
                                                schedule.LastCheckIn         = endOfCheckinWindow;
                                                location.LastCheckIn         = endOfCheckinWindow;
                                                group.LastCheckIn            = endOfCheckinWindow;
                                                groupType.LastCheckIn        = endOfCheckinWindow;
                                                previousAttender.LastCheckIn = endOfCheckinWindow;
                                            }

                                            // finished finding assignment, verify everything is selected
                                            schedule.Selected            = true;
                                            schedule.PreSelected         = true;
                                            location.Selected            = true;
                                            location.PreSelected         = true;
                                            group.Selected               = true;
                                            group.PreSelected            = true;
                                            groupType.Selected           = true;
                                            groupType.PreSelected        = true;
                                            previousAttender.Selected    = true;
                                            previousAttender.PreSelected = true;
                                            assignmentsGiven++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }
示例#19
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, Rock.Model.WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            var checkInState = GetCheckInState(entity, out errorMessages);

            if (checkInState == null)
            {
                return(false);
            }

            int selectFromDaysBack    = checkInState.CheckInType.AutoSelectDaysBack;
            var roomBalanceGroupTypes = GetAttributeValue(action, "RoomBalanceGrouptypes").SplitDelimitedValues().AsGuidList();
            int roomBalanceOverride   = GetAttributeValue(action, "BalancingOverride").AsIntegerOrNull() ?? 5;
            int maxAssignments        = GetAttributeValue(action, "MaxAssignments").AsIntegerOrNull() ?? 5;
            var excludedLocations     = GetAttributeValue(action, "ExcludedLocations").SplitDelimitedValues(whitespace: false)
                                        .Select(s => s.Trim());

            // get the admin-selected attribute key instead of using a hardcoded key
            var personSpecialNeedsKey  = string.Empty;
            var personSpecialNeedsGuid = GetAttributeValue(action, "PersonSpecialNeedsAttribute").AsGuid();

            if (personSpecialNeedsGuid != Guid.Empty)
            {
                personSpecialNeedsKey = AttributeCache.Read(personSpecialNeedsGuid, rockContext).Key;
            }

            // log a warning if the attribute is missing or invalid
            if (string.IsNullOrWhiteSpace(personSpecialNeedsKey))
            {
                action.AddLogEntry(string.Format("The Person Special Needs attribute is not selected or invalid for '{0}'.", action.ActionType.Name));
            }

            var family = checkInState.CheckIn.Families.FirstOrDefault(f => f.Selected);

            if (family != null)
            {
                var cutoffDate        = RockDateTime.Today.AddDays(selectFromDaysBack * -1);
                var attendanceService = new AttendanceService(rockContext);

                // only process people who have been here before
                foreach (var previousAttender in family.People.Where(p => p.Selected && !p.FirstTime))
                {
                    // get a list of this person's available grouptypes
                    var availableGroupTypeIds = previousAttender.GroupTypes.Select(gt => gt.GroupType.Id).ToList();

                    var lastDateAttendances = attendanceService.Queryable().Where(a =>
                                                                                  a.PersonAlias.PersonId == previousAttender.Person.Id &&
                                                                                  availableGroupTypeIds.Contains(a.Group.GroupTypeId) &&
                                                                                  a.StartDateTime >= cutoffDate && a.DidAttend == true)
                                              .OrderByDescending(a => a.StartDateTime).Take(maxAssignments)
                                              .ToList();

                    if (lastDateAttendances.Any())
                    {
                        var lastAttended   = lastDateAttendances.Max(a => a.StartDateTime).Date;
                        var numAttendances = lastDateAttendances.Count(a => a.StartDateTime >= lastAttended);
                        foreach (var groupAttendance in lastDateAttendances.Where(a => a.StartDateTime >= lastAttended))
                        {
                            bool currentlyCheckedIn = false;
                            var  serviceCutoff      = groupAttendance.StartDateTime;
                            if (serviceCutoff > RockDateTime.Now.Date)
                            {
                                // calculate the service window to determine if people are still checked in
                                var serviceTime  = groupAttendance.StartDateTime.Date + groupAttendance.Schedule.NextStartDateTime.Value.TimeOfDay;
                                var serviceStart = serviceTime.AddMinutes((groupAttendance.Schedule.CheckInStartOffsetMinutes ?? 0) * -1.0);
                                serviceCutoff      = serviceTime.AddMinutes((groupAttendance.Schedule.CheckInEndOffsetMinutes ?? 0));
                                currentlyCheckedIn = RockDateTime.Now > serviceStart && RockDateTime.Now < serviceCutoff;
                            }

                            // override exists in case they are currently checked in or have special needs
                            bool useCheckinOverride = currentlyCheckedIn || previousAttender.Person.GetAttributeValue(personSpecialNeedsKey).AsBoolean();

                            // get a list of room balanced grouptype ID's since CheckInGroup model is a shallow clone
                            var roomBalanceGroupTypeIds = previousAttender.GroupTypes.Where(gt => roomBalanceGroupTypes.Contains(gt.GroupType.Guid))
                                                          .Select(gt => gt.GroupType.Id).ToList();

                            // Start with filtered groups unless they have abnormal age and grade parameters (1%)
                            var groupType = previousAttender.GroupTypes.FirstOrDefault(gt => gt.GroupType.Id == groupAttendance.Group.GroupTypeId && (!gt.ExcludedByFilter || useCheckinOverride));
                            if (groupType != null)
                            {
                                CheckInGroup group = null;
                                if (groupType.Groups.Count == 1)
                                {
                                    // Only a single group is open
                                    group = groupType.Groups.FirstOrDefault(g => !g.ExcludedByFilter || useCheckinOverride);
                                }
                                else
                                {
                                    // Pick the group they last attended, as long as it's open or what they're currently checked into
                                    group = groupType.Groups.FirstOrDefault(g => g.Group.Id == groupAttendance.GroupId && (!g.ExcludedByFilter || useCheckinOverride));

                                    // room balance only on new check-ins
                                    if (group != null && roomBalanceGroupTypeIds.Contains(group.Group.GroupTypeId) && !useCheckinOverride)
                                    {
                                        //TODO: use KioskLocationAttendance and group.AvailableForSchedule to room balance by service time attendance, not the entire day
                                        var currentAttendance   = group.Locations.Select(l => KioskLocationAttendance.Read(l.Location.Id).CurrentCount).Sum();
                                        var lowestAttendedGroup = groupType.Groups.Where(g => !g.ExcludedByFilter && !excludedLocations.Contains(g.Group.Name))
                                                                  .Select(g => new { Group = g, Attendance = g.Locations.Select(l => KioskLocationAttendance.Read(l.Location.Id).CurrentCount).Sum() })
                                                                  .OrderBy(g => g.Attendance)
                                                                  .FirstOrDefault();

                                        if (lowestAttendedGroup != null && lowestAttendedGroup.Attendance < (currentAttendance - roomBalanceOverride + 1))
                                        {
                                            group = lowestAttendedGroup.Group;
                                        }
                                    }
                                }

                                if (group != null)
                                {
                                    CheckInLocation location = null;
                                    if (group.Locations.Count == 1)
                                    {
                                        // Only a single location is open
                                        location = group.Locations.FirstOrDefault(l => !l.ExcludedByFilter || useCheckinOverride);
                                    }
                                    else
                                    {
                                        // Pick the location they last attended, as long as it's open or what they're currently checked into
                                        location = group.Locations.FirstOrDefault(l => l.Location.Id == groupAttendance.LocationId && (!l.ExcludedByFilter || useCheckinOverride));

                                        // room balance only on new check-ins
                                        if (location != null && roomBalanceGroupTypeIds.Contains(group.Group.GroupTypeId) && !useCheckinOverride)
                                        {
                                            //TODO: use KioskLocationAttendance and location.AvailableForSchedule to room balance by service time attendance, not the entire day
                                            var currentAttendance      = KioskLocationAttendance.Read(location.Location.Id).CurrentCount;
                                            var lowestAttendedLocation = group.Locations.Where(l => !l.ExcludedByFilter && !excludedLocations.Contains(l.Location.Name))
                                                                         .Select(l => new { Location = l, Attendance = KioskLocationAttendance.Read(l.Location.Id).CurrentCount })
                                                                         .OrderBy(l => l.Attendance)
                                                                         .FirstOrDefault();

                                            if (lowestAttendedLocation != null && lowestAttendedLocation.Attendance < (currentAttendance - roomBalanceOverride + 1))
                                            {
                                                location = lowestAttendedLocation.Location;
                                            }
                                        }
                                    }

                                    if (location != null)
                                    {
                                        CheckInSchedule schedule = null;
                                        if (location.Schedules.Count == 1)
                                        {
                                            schedule = location.Schedules.FirstOrDefault(s => !s.ExcludedByFilter || useCheckinOverride);
                                        }
                                        else
                                        {
                                            // if assigning to multiple services or currently checked in (not SN, otherwise they would get the wrong auto-schedule)
                                            if (numAttendances > 1 || currentlyCheckedIn)
                                            {
                                                // pick what they last attended last
                                                schedule = location.Schedules.FirstOrDefault(s => s.Schedule.Id == groupAttendance.ScheduleId && (!s.ExcludedByFilter || useCheckinOverride));
                                            }

                                            // otherwise pick the earliest available schedule
                                            schedule = schedule ?? location.Schedules.OrderBy(s => s.Schedule.StartTimeOfDay).FirstOrDefault(s => !s.ExcludedByFilter);
                                        }

                                        if (schedule != null)
                                        {
                                            // it's impossible to currently be checked in unless these match exactly
                                            if (group.Group.Id == groupAttendance.GroupId && location.Location.Id == groupAttendance.LocationId && schedule.Schedule.Id == groupAttendance.ScheduleId)
                                            {
                                                // Checkout would've removed the attendance or set the EndDateTime
                                                var endOfCheckinWindow = groupAttendance.EndDateTime ?? serviceCutoff;
                                                schedule.LastCheckIn         = endOfCheckinWindow;
                                                location.LastCheckIn         = endOfCheckinWindow;
                                                group.LastCheckIn            = endOfCheckinWindow;
                                                groupType.LastCheckIn        = endOfCheckinWindow;
                                                previousAttender.LastCheckIn = endOfCheckinWindow;
                                            }

                                            // finished finding assignment, verify everything is selected
                                            schedule.Selected            = true;
                                            schedule.PreSelected         = true;
                                            location.Selected            = true;
                                            location.PreSelected         = true;
                                            group.Selected               = true;
                                            group.PreSelected            = true;
                                            groupType.Selected           = true;
                                            groupType.PreSelected        = true;
                                            groupType.Selected           = true;
                                            groupType.PreSelected        = true;
                                            previousAttender.Selected    = true;
                                            previousAttender.PreSelected = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }
示例#20
0
        /// <summary>
        /// Loads the person schedules.
        /// </summary>
        /// <param name="person">The person.</param>
        /// <param name="attendanceScheduledLookup">The attendance scheduled lookup.</param>
        /// <param name="kioskGroupTypeLookup">The kiosk group type lookup.</param>
        /// <param name="loadSelectedOnly">if set to <c>true</c> [load selected only].</param>
        /// <param name="remove">if set to <c>true</c> [remove], schedule will be removed vs marked excluded when doesn't meet requirements</param>
        /// <param name="checkInState">State of the check in.</param>
        private void LoadPersonSchedules(CheckInPerson person, List <PersonAttendanceScheduled> attendanceScheduledLookup, Dictionary <int, KioskGroupType> kioskGroupTypeLookup, bool loadSelectedOnly, bool remove, CheckInState checkInState)
        {
            var personGroups = person.GetGroupTypes(loadSelectedOnly).SelectMany(gt => gt.GetGroups(loadSelectedOnly)).ToList();

            foreach (var group in personGroups)
            {
                var kioskGroup = kioskGroupTypeLookup.GetValueOrNull(group.Group.GroupTypeId)?.KioskGroups?.Where(g => g.Group.Id == group.Group.Id && g.IsCheckInActive)
                                 .FirstOrDefault();

                if (kioskGroup == null)
                {
                    continue;
                }

                var groupType = GroupTypeCache.Get(group.Group.GroupTypeId);

                foreach (var location in group.GetLocations(loadSelectedOnly))
                {
                    var kioskLocation = kioskGroup.KioskLocations
                                        .Where(l => l.Location.Id == location.Location.Id && l.IsCheckInActive)
                                        .FirstOrDefault();

                    if (kioskLocation == null)
                    {
                        continue;
                    }

                    foreach (var kioskSchedule in kioskLocation.KioskSchedules.Where(s => s.IsCheckInActive))
                    {
                        bool?personIsScheduled = null;
                        var  attendanceRecordRequiredForCheckIn = group.Group.AttendanceRecordRequiredForCheckIn;

                        // if the groupType currently doesn't have scheduling enabled, ignore the group's AttendanceRecordRequiredForCheckIn setting, and just have it be ScheduleNotRequired
                        if (groupType.IsSchedulingEnabled == false)
                        {
                            attendanceRecordRequiredForCheckIn = AttendanceRecordRequiredForCheckIn.ScheduleNotRequired;
                        }

                        // if ScheduleRequired or PreSelect, we'll need to see if the person is scheduled
                        if (group.Group.AttendanceRecordRequiredForCheckIn != AttendanceRecordRequiredForCheckIn.ScheduleNotRequired)
                        {
                            personIsScheduled = attendanceScheduledLookup?.Any(a =>
                                                                               a.PersonId == person.Person.Id &&
                                                                               a.GroupId == group.Group.Id &&
                                                                               a.LocationId == location.Location.Id &&
                                                                               a.ScheduleId == kioskSchedule.Schedule.Id);
                        }

                        bool excludeSchedule = false;

                        if (group.Group.AttendanceRecordRequiredForCheckIn == AttendanceRecordRequiredForCheckIn.ScheduleRequired)
                        {
                            if (personIsScheduled != true)
                            {
                                // don't add to the person's available schedules
                                excludeSchedule = true;
                            }
                        }

                        bool preSelectForOccurrence = false;

                        if (group.Group.AttendanceRecordRequiredForCheckIn == AttendanceRecordRequiredForCheckIn.PreSelect)
                        {
                            preSelectForOccurrence = personIsScheduled == true;
                        }

                        location.PreSelected = preSelectForOccurrence;

                        if (excludeSchedule && remove)
                        {
                            // the schedule doesn't meet requirements, and the option for Excluding vs Removing is remove, so don't add it
                            continue;
                        }

                        if (!location.Schedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id))
                        {
                            var checkInSchedule = new CheckInSchedule();
                            checkInSchedule.Schedule         = kioskSchedule.Schedule.Clone(false);
                            checkInSchedule.CampusId         = kioskSchedule.CampusId;
                            checkInSchedule.StartTime        = kioskSchedule.StartTime;
                            checkInSchedule.PreSelected      = preSelectForOccurrence;
                            checkInSchedule.ExcludedByFilter = excludeSchedule;
                            location.Schedules.Add(checkInSchedule);
                        }

                        if (checkInState.CheckInType?.TypeOfCheckin == TypeOfCheckin.Family &&
                            !person.PossibleSchedules.Any(s => s.Schedule.Id == kioskSchedule.Schedule.Id))
                        {
                            var checkInSchedule = new CheckInSchedule();
                            checkInSchedule.Schedule         = kioskSchedule.Schedule.Clone(false);
                            checkInSchedule.CampusId         = kioskSchedule.CampusId;
                            checkInSchedule.StartTime        = kioskSchedule.StartTime;
                            checkInSchedule.PreSelected      = preSelectForOccurrence;
                            checkInSchedule.ExcludedByFilter = excludeSchedule;

                            person.PossibleSchedules.Add(checkInSchedule);
                        }
                    }
                }
            }
        }
示例#21
0
        private CheckInStatus DehydrateStatus(CheckInStatus status)
        {
            var checkinstatus = new CheckInStatus
            {
                SearchType  = status.SearchType,
                SearchValue = status.SearchValue,
                Families    = new List <CheckInFamily>()
            };

            foreach (var family in status.Families)
            {
                var checkinFamily = new CheckInFamily()
                {
                    Selected      = family.Selected,
                    Caption       = family.Caption,
                    SubCaption    = family.SubCaption,
                    AttendanceIds = family.AttendanceIds,
                    FirstNames    = family.FirstNames,
                    Group         = new Group()
                    {
                        Id = family.Group.Id
                    },
                    People = new List <CheckInPerson>()
                };
                checkinstatus.Families.Add(checkinFamily);

                foreach (var person in family.People)
                {
                    var checkInPerson = new CheckInPerson
                    {
                        GroupTypes   = new List <CheckInGroupType>(),
                        FirstTime    = person.FirstTime,
                        FamilyMember = person.FamilyMember,
                        Person       = new Person {
                            Id = person.Person.Id
                        },
                        PreSelected      = person.PreSelected,
                        SecurityCode     = person.SecurityCode,
                        ExcludedByFilter = person.ExcludedByFilter,
                        Selected         = person.Selected
                    };
                    checkinFamily.People.Add(checkInPerson);

                    foreach (var grouptype in person.GroupTypes)
                    {
                        var checkinGroupType = new CheckInGroupType
                        {
                            GroupType        = grouptype.GroupType,
                            Selected         = grouptype.Selected,
                            PreSelected      = grouptype.PreSelected,
                            ExcludedByFilter = grouptype.ExcludedByFilter,
                            Groups           = new List <CheckInGroup>()
                        };
                        checkInPerson.GroupTypes.Add(checkinGroupType);

                        foreach (var group in grouptype.Groups)
                        {
                            var checkinGroup = new CheckInGroup
                            {
                                Group = new Group {
                                    Id = group.Group.Id
                                },
                                Selected         = group.Selected,
                                PreSelected      = group.PreSelected,
                                ExcludedByFilter = group.ExcludedByFilter,
                                Locations        = new List <CheckInLocation>()
                            };
                            checkinGroupType.Groups.Add(group);

                            foreach (var location in group.Locations)
                            {
                                var checkinLocation = new CheckInLocation
                                {
                                    Location = new Location {
                                        Id = location.Location.Id
                                    },
                                    Selected         = location.Selected,
                                    PreSelected      = location.PreSelected,
                                    ExcludedByFilter = location.ExcludedByFilter,
                                    CampusId         = location.CampusId,
                                    Schedules        = new List <CheckInSchedule>()
                                };
                                checkinGroup.Locations.Add(checkinLocation);

                                foreach (var schedule in location.Schedules)
                                {
                                    var checkinSchedule = new CheckInSchedule
                                    {
                                        Schedule = new Schedule {
                                            Id = schedule.Schedule.Id
                                        },
                                        Selected         = schedule.Selected,
                                        PreSelected      = schedule.PreSelected,
                                        ExcludedByFilter = schedule.ExcludedByFilter,
                                        CampusId         = schedule.CampusId,
                                        StartTime        = schedule.StartTime
                                    };
                                    checkinLocation.Schedules.Add(checkinSchedule);
                                }
                            }
                        }
                    }
                }
            }
            return(checkinstatus);
        }