/// <summary>
        /// Gets the specified occurrence record, creating it if necessary. Ensures that an AttendanceOccurrence
        /// record exists for the specified date, schedule, locationId and group. If it doesn't exist, it is
        /// created and saved to the database.
        /// NOTE: When looking for a matching occurrence, if null groupId, locationId or scheduleId is given
        /// any matching record must also not have a group, location or schedule.
        /// </summary>
        /// <param name="occurrenceDate">The occurrence date.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="scheduleId">The schedule identifier.</param>
        /// <param name="includes">Allows including attendance occurrence virtual properties like Attendees.</param>
        /// <param name="attendanceTypeValueId">The attendance type identifier.</param>
        /// <returns>
        /// An existing or new attendance occurrence
        /// </returns>
        public AttendanceOccurrence GetOrAdd(DateTime occurrenceDate, int?groupId, int?locationId, int?scheduleId, string includes, int?attendanceTypeValueId)
        {
            var occurrence = Get(occurrenceDate, groupId, locationId, scheduleId, includes);

            if (occurrence == null)
            {
                // If occurrence does not yet exist, create it
                // A new context is used so the occurrence can be saved and used on multiple new attendance records that will be saved at once.
                using (var newContext = new RockContext())
                {
                    occurrence = new AttendanceOccurrence
                    {
                        OccurrenceDate        = occurrenceDate,
                        GroupId               = groupId,
                        LocationId            = locationId,
                        ScheduleId            = scheduleId,
                        AttendanceTypeValueId = attendanceTypeValueId
                    };

                    var newOccurrenceService = new AttendanceOccurrenceService(newContext);
                    newOccurrenceService.Add(occurrence);
                    newContext.SaveChanges();

                    // Query for the new occurrence using original context.
                    occurrence = Get(occurrence.Id);
                }
            }

            return(occurrence);
        }
        public AttendanceOccurrence GetOrCreateAttendanceOccurrence(DateTime occurrenceDate, int scheduleId, int?locationId, int groupId)
        {
            // There is a unique constraint on OccurrenceDate, ScheduleId, LocationId and GroupId. So there is at most one record.
            var attendanceOccurrenceQuery = this.Queryable().Where(a =>
                                                                   a.OccurrenceDate == occurrenceDate.Date &&
                                                                   a.ScheduleId.HasValue && a.ScheduleId == scheduleId &&
                                                                   a.GroupId.HasValue && a.GroupId == groupId);

            if (locationId.HasValue)
            {
                attendanceOccurrenceQuery = attendanceOccurrenceQuery.Where(a => a.LocationId.HasValue && a.LocationId.Value == locationId.Value);
            }
            else
            {
                attendanceOccurrenceQuery = attendanceOccurrenceQuery.Where(a => a.LocationId.HasValue == false);
            }

            var attendanceOccurrence = attendanceOccurrenceQuery.FirstOrDefault();

            if (attendanceOccurrence != null)
            {
                return(attendanceOccurrence);
            }
            else
            {
                // if the attendance occurrence is not found, create and save it using a separate context, then get it with this context using the created attendanceOccurrence.Id
                int attendanceOccurrenceId;
                using (var rockContext = new RockContext())
                {
                    var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);

                    if (attendanceOccurrence == null)
                    {
                        attendanceOccurrence = new AttendanceOccurrence
                        {
                            GroupId        = groupId,
                            LocationId     = locationId,
                            ScheduleId     = scheduleId,
                            OccurrenceDate = occurrenceDate
                        };

                        attendanceOccurrenceService.Add(attendanceOccurrence);
                        rockContext.SaveChanges();
                    }

                    attendanceOccurrenceId = attendanceOccurrence.Id;
                }

                return(this.Get(attendanceOccurrence.Id));
            }
        }
            private LaunchMemberAttendedGroupWorkflow.Message GetLaunchMemberAttendedGroupWorkflowMessage()
            {
                var launchMemberAttendedGroupWorkflowMsg = new LaunchMemberAttendedGroupWorkflow.Message();

                if (State != EntityContextState.Deleted)
                {
                    // Get the attendance record
                    var attendance = 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 = State == EntityContextState.Added;

                        // If not an add, check previous DidAttend value
                        if (!valid)
                        {
                            // Only use changes where DidAttend was previously not true
                            valid = !( bool )Entry.OriginalValues.GetReadOnlyValueOrDefault("DidAttend", false);
                        }

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

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

                                if (occ.Group != null)
                                {
                                    launchMemberAttendedGroupWorkflowMsg.GroupTypeId = occ.Group.GroupTypeId;
                                }
                            }
                        }
                    }
                }

                return(launchMemberAttendedGroupWorkflowMsg);
            }
Esempio n. 4
0
        private void ProcessObsoleteOccurrenceFields(DbEntityEntry entry)
        {
            if (entry.State == EntityState.Modified || entry.State == EntityState.Added)
            {
                // NOTE: If they only changed StartDateTime, don't change the Occurrence record. We want to support letting StartDateTime be a different Date than the OccurrenceDate in that situation
                if (_updatedObsoleteGroupId || _updatedObsoleteLocationId || _updatedObsoleteScheduleId || _updatedObsoleteDidNotOccur)
                {
                    if (_updatedObsoleteGroupId || _updatedObsoleteLocationId || _updatedObsoleteScheduleId)
                    {
                        // if they changed or set stuff related to AttendanceOccurrence (not including DidNotOccur or StartDateTime) thru obsolete properties, find or create a Matching AttendanceOccurrence Record
                        using (var attendanceOccurrenceRockContext = new RockContext())
                        {
                            var attendanceOccurrenceService = new AttendanceOccurrenceService(attendanceOccurrenceRockContext);

                            // if GroupId,LocationId, or ScheduleId changed, use StartDateTime's Date as the OccurrenceDate to look up AttendanceOccurrence since it is really a completely different Occurrence if Group,Location or Schedule changes
                            var occurrenceDate = this.StartDateTime.Date;

                            var attendanceOccurrence = attendanceOccurrenceService.Queryable().Where(a => a.GroupId == this.GroupId && a.LocationId == this.LocationId && a.ScheduleId == this.ScheduleId && a.OccurrenceDate == occurrenceDate).FirstOrDefault();
                            if (attendanceOccurrence != null)
                            {
                                // found a matching attendanceOccurrence, so use that
                                if (_updatedObsoleteDidNotOccur && attendanceOccurrence.DidNotOccur != this.DidNotOccur)
                                {
                                    // If DidNotOccur also changed, update the DidNotOccur for the attendanceOccurrence
                                    // NOTE: This will update *all* Attendances' DidNotOccur for this AttendanceOccurrence. That is OK. That is what we want to happen.
                                    attendanceOccurrence.DidNotOccur = this.DidNotOccur;
                                    attendanceOccurrenceRockContext.SaveChanges();
                                }

                                if (attendanceOccurrence.Id != this.OccurrenceId)
                                {
                                    this.OccurrenceId = attendanceOccurrence.Id;
                                }
                            }
                            else
                            {
                                // didn't find a matching attendanceOccurrence, so create and insert a new one
                                attendanceOccurrence = new AttendanceOccurrence
                                {
                                    GroupId        = this.GroupId,
                                    LocationId     = this.LocationId,
                                    ScheduleId     = this.ScheduleId,
                                    DidNotOccur    = this.DidNotOccur,
                                    OccurrenceDate = occurrenceDate
                                };

                                attendanceOccurrenceService.Add(attendanceOccurrence);
                                attendanceOccurrenceRockContext.SaveChanges();
                                this.OccurrenceId = attendanceOccurrence.Id;
                            }
                        }
                    }
                    else if (_updatedObsoleteDidNotOccur)
                    {
                        // if they only changed DidNotOccur, but not any of the other obsolete attendanceoccurrence properties, just change the DidNotOccur on the existing AttendanceOccurrence record
                        if (this.Occurrence != null)
                        {
                            this.Occurrence.DidNotOccur = _updatedObsoleteDidNotOccurValue;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Adds or updates an attendance record and will create the occurrence if needed
        /// </summary>
        /// <param name="personAliasId">The person alias identifier.</param>
        /// <param name="checkinDateTime">The checkin date time.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="locationId">The location identifier.</param>
        /// <param name="scheduleId">The schedule identifier.</param>
        /// <param name="campusId">The campus identifier.</param>
        /// <param name="deviceId">The device identifier.</param>
        /// <param name="searchTypeValueId">The search type value identifier.</param>
        /// <param name="searchValue">The search value.</param>
        /// <param name="searchResultGroupId">The search result group identifier.</param>
        /// <param name="attendanceCodeId">The attendance code identifier.</param>
        /// <param name="checkedInByPersonAliasId">The checked in by person alias identifier.</param>
        /// <returns></returns>
        public Attendance AddOrUpdate(int?personAliasId, DateTime checkinDateTime,
                                      int?groupId, int?locationId, int?scheduleId, int?campusId, int?deviceId,
                                      int?searchTypeValueId, string searchValue, int?searchResultGroupId, int?attendanceCodeId, int?checkedInByPersonAliasId)
        {
            // Check to see if an occurrence exists already
            var occurrenceService = new AttendanceOccurrenceService((RockContext)Context);
            var occurrence        = occurrenceService.Get(checkinDateTime.Date, groupId, locationId, scheduleId);

            if (occurrence == null)
            {
                // If occurrence does not yet exists, use a new context and create it
                using (var newContext = new RockContext())
                {
                    occurrence = new AttendanceOccurrence
                    {
                        OccurrenceDate = checkinDateTime.Date,
                        GroupId        = groupId,
                        LocationId     = locationId,
                        ScheduleId     = scheduleId,
                    };

                    var newOccurrenceService = new AttendanceOccurrenceService(newContext);
                    newOccurrenceService.Add(occurrence);
                    newContext.SaveChanges();

                    // Query for the new occurrence using original context.
                    occurrence = occurrenceService.Get(occurrence.Id);
                }
            }

            // If we still don't have an occurrence record (i.e. validation failed) return null
            if (occurrence == null)
            {
                return(null);
            }

            // Query for existing attendance record
            Attendance attendance = null;

            if (personAliasId.HasValue)
            {
                attendance = occurrence.Attendees
                             .FirstOrDefault(a =>
                                             a.PersonAliasId.HasValue &&
                                             a.PersonAliasId.Value == personAliasId.Value);
            }

            // If an attendance record doesn't exist for the occurrence, add a new record
            if (attendance == null)
            {
                attendance = ((RockContext)Context).Attendances.Create();
                {
                    attendance.Occurrence    = occurrence;
                    attendance.OccurrenceId  = occurrence.Id;
                    attendance.PersonAliasId = personAliasId;
                };
                Add(attendance);
            }

            // Update details of the attendance (do not overwrite an existing value with an empty value)
            if (campusId.HasValue)
            {
                attendance.CampusId = campusId.Value;
            }
            if (deviceId.HasValue)
            {
                attendance.DeviceId = deviceId.Value;
            }
            if (searchTypeValueId.HasValue)
            {
                attendance.SearchTypeValueId = searchTypeValueId;
            }
            if (searchValue.IsNotNullOrWhiteSpace())
            {
                attendance.SearchValue = searchValue;
            }
            if (checkedInByPersonAliasId.HasValue)
            {
                attendance.CheckedInByPersonAliasId = checkedInByPersonAliasId.Value;
            }
            if (searchResultGroupId.HasValue)
            {
                attendance.SearchResultGroupId = searchResultGroupId;
            }
            if (attendanceCodeId.HasValue)
            {
                attendance.AttendanceCodeId = attendanceCodeId;
            }
            attendance.StartDateTime = checkinDateTime;
            attendance.DidAttend     = true;

            return(attendance);
        }
            /// <summary>
            /// Method that will be called on an entity immediately before the item is saved by context
            /// </summary>
            protected override void PreSave()
            {
                PersonAttendanceHistoryChangeList = new History.HistoryChangeList();

                _isDeleted = State == EntityContextState.Deleted;
                bool previousDidAttendValue;

                bool previouslyDeclined;

                if (State == EntityContextState.Added)
                {
                    previousDidAttendValue = false;
                    previouslyDeclined     = false;
                }
                else
                {
                    // get original values so we can detect whether the value changed
                    previousDidAttendValue = ( bool )Entry.OriginalValues.GetReadOnlyValueOrDefault("DidAttend", false);
                    previouslyDeclined     = (Entry.OriginalValues.GetReadOnlyValueOrDefault("RSVP", null) as RSVP? ) == RSVP.No;
                }

                // if the record was changed to Declined, queue a GroupScheduleCancellationTransaction in PostSaveChanges
                _declinedScheduledAttendance = (previouslyDeclined == false) && Entity.IsScheduledPersonDeclined();

                if (previousDidAttendValue == false && Entity.DidAttend == true)
                {
                    var launchMemberAttendedGroupWorkflowMsg = GetLaunchMemberAttendedGroupWorkflowMessage();
                    launchMemberAttendedGroupWorkflowMsg.Send();
                }

                var attendance = this.Entity;

                if (State == EntityContextState.Modified)
                {
                    preSavePersonAliasId = attendance.PersonAliasId;
                    var originalOccurrenceId = ( int? )OriginalValues[nameof(attendance.OccurrenceId)];
                    if (originalOccurrenceId.HasValue && attendance.OccurrenceId != originalOccurrenceId.Value)
                    {
                        var attendanceOccurrenceService = new AttendanceOccurrenceService(this.RockContext);
                        var originalOccurrence          = attendanceOccurrenceService.GetNoTracking(originalOccurrenceId.Value);
                        var currentOccurrence           = attendanceOccurrenceService.GetNoTracking(attendance.OccurrenceId);
                        if (originalOccurrence != null && currentOccurrence != null)
                        {
                            if (originalOccurrence.GroupId != currentOccurrence.GroupId)
                            {
                                History.EvaluateChange(PersonAttendanceHistoryChangeList, "Group", originalOccurrence.Group?.Name, currentOccurrence.Group?.Name);
                            }

                            if (originalOccurrence.ScheduleId.HasValue && currentOccurrence.ScheduleId.HasValue && originalOccurrence.ScheduleId.Value != currentOccurrence.ScheduleId.Value)
                            {
                                History.EvaluateChange(PersonAttendanceHistoryChangeList, "Schedule", NamedScheduleCache.Get(originalOccurrence.ScheduleId.Value)?.Name, NamedScheduleCache.Get(currentOccurrence.ScheduleId.Value)?.Name);
                            }

                            if (originalOccurrence.LocationId.HasValue && currentOccurrence.LocationId.HasValue && originalOccurrence.LocationId.Value != currentOccurrence.LocationId.Value)
                            {
                                History.EvaluateChange(PersonAttendanceHistoryChangeList, "Location", NamedLocationCache.Get(originalOccurrence.LocationId.Value)?.Name, NamedLocationCache.Get(currentOccurrence.LocationId.Value)?.Name);
                            }
                        }
                    }
                }
                else if (State == EntityContextState.Deleted)
                {
                    preSavePersonAliasId = ( int? )OriginalValues[nameof(attendance.PersonAliasId)];
                    PersonAttendanceHistoryChangeList.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Attendance");
                }

                base.PreSave();
            }