Example #1
0
        /// <summary>
        /// Uses the filter information in the CalendarProps object to get a list of events
        /// </summary>
        /// <param name="calendarProps">The calendar props.</param>
        /// <returns></returns>
        private List <EventItem> GetEventItems(CalendarProps calendarProps)
        {
            RockContext rockContext = new RockContext();

            EventCalendarItemService eventCalendarItemService = new EventCalendarItemService(rockContext);
            var eventIdsForCalendar = eventCalendarItemService
                                      .Queryable()
                                      .Where(i => i.EventCalendarId == calendarProps.CalendarId)
                                      .Select(i => i.EventItemId)
                                      .ToList();

            EventItemService eventItemService = new EventItemService(rockContext);
            var eventQueryable = eventItemService
                                 .Queryable("EventItemAudiences, EventItemOccurrences.Schedule")
                                 .Where(e => eventIdsForCalendar.Contains(e.Id))
                                 .Where(e => e.EventItemOccurrences.Any(o => o.Schedule.EffectiveStartDate <= calendarProps.EndDate && calendarProps.StartDate <= o.Schedule.EffectiveEndDate))
                                 .Where(e => e.IsActive == true)
                                 .Where(e => e.IsApproved);

            // For Campus
            if (calendarProps.CampusIds.Any())
            {
                eventQueryable = eventQueryable.Where(e => e.EventItemOccurrences.Any(c => !c.CampusId.HasValue || calendarProps.CampusIds.Contains(c.CampusId.Value)));
            }

            // For Audience
            if (calendarProps.AudienceIds.Any())
            {
                eventQueryable = eventQueryable.Where(e => e.EventItemAudiences.Any(c => calendarProps.AudienceIds.Contains(c.DefinedValueId)));
            }

            return(eventQueryable.ToList());
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EventItemPicker" /> class.
        /// </summary>
        public EventItemPicker()
        {
            this.Items.Clear();
            this.Items.Add( new ListItem() );

            using ( var rockContext = new RockContext() )
            {

                var calendarItems = new EventCalendarItemService( rockContext ).Queryable()
                                .Select( i => new
                                    {
                                        Calendar = i.EventCalendar.Name,
                                        Id = i.EventItem.Id,
                                        Name = i.EventItem.Name
                                    } )
                                .OrderBy( i => i.Calendar )
                                .ToList();

                foreach ( var calendarItem in calendarItems )
                {
                    ListItem listItem = new ListItem( calendarItem.Name, calendarItem.Id.ToString() );
                    listItem.Attributes["OptionGroup"] = calendarItem.Calendar;
                    this.Items.Add( listItem );
                }
            }
        }
        /// <summary>
        /// Loads the drop down items.
        /// </summary>
        private void LoadDropDownItems()
        {
            this.Items.Clear();
            this.Items.Add(new ListItem());

            using (var rockContext = new RockContext())
            {
                var calendarItems = new EventCalendarItemService(rockContext).Queryable()
                                    .Select(i => new
                {
                    Calendar = i.EventCalendar.Name,
                    Id       = i.EventItem.Id,
                    Name     = i.EventItem.Name,
                    IsActive = i.EventItem.IsActive
                })
                                    .OrderBy(i => i.Calendar)
                                    .ThenBy(i => i.Name)
                                    .ToList();

                if (!IncludeInactive)
                {
                    calendarItems = calendarItems.Where(i => i.IsActive).ToList();
                }

                foreach (var calendarItem in calendarItems)
                {
                    ListItem listItem = new ListItem(calendarItem.Name, calendarItem.Id.ToString());
                    listItem.Attributes["OptionGroup"] = calendarItem.Calendar;
                    this.Items.Add(listItem);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EventItemPicker" /> class.
        /// </summary>
        public EventItemPicker()
        {
            this.Items.Clear();
            this.Items.Add(new ListItem());

            using (var rockContext = new RockContext())
            {
                var calendarItems = new EventCalendarItemService(rockContext).Queryable()
                                    .Select(i => new
                {
                    Calendar = i.EventCalendar.Name,
                    Id       = i.EventItem.Id,
                    Name     = i.EventItem.Name
                })
                                    .OrderBy(i => i.Calendar)
                                    .ToList();

                foreach (var calendarItem in calendarItems)
                {
                    ListItem listItem = new ListItem(calendarItem.Name, calendarItem.Id.ToString());
                    listItem.Attributes["OptionGroup"] = calendarItem.Calendar;
                    this.Items.Add(listItem);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Adds the event to a Calendar.
        /// </summary>
        /// <param name="eventItem">The event</param>
        /// <param name="calendar">The calendar</param>
        /// <param name="created">If a new calendar item was created</param>
        /// <returns>The calendar item for the event</returns>
        public static void RemoveFromCalendar(this EventItem eventItem, EventCalendarItemService eventCalendarItemService, EventCalendarCache calendar, out bool removed)
        {
            removed = false;
            if (calendar == null)
            {
                return;
            }
            var calendarItem = eventItem.EventCalendarItems.FirstOrDefault(ci => ci.EventCalendarId == calendar.Id);

            if (calendarItem != null)
            {
                removed = true;
                eventCalendarItemService.Delete(calendarItem);
            }
        }
Example #6
0
        /// <summary>
        /// Handles the Click event of the lbCalendarItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void lbCalendarItem_Click(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var eventItem = new EventCalendarItemService(rockContext)
                                .Get(PageParameter("EventItemId").AsInteger());

                if (eventItem != null)
                {
                    var qryParams = new Dictionary <string, string>();
                    qryParams.Add("EventItemId", eventItem.Id.ToString());
                    qryParams.Add("EventCalendarId", eventItem.EventCalendarId.ToString());
                    NavigateToParentPage(qryParams);
                }
            }
        }
Example #7
0
        /// <summary>
        /// Handles the Click event of the lbCalendarDetail control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void lbCalendarDetail_Click(object sender, EventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                var eventItem = new EventCalendarItemService(rockContext)
                                .Get(PageParameter("EventItemId").AsInteger());

                if (eventItem != null)
                {
                    var qryParams = new Dictionary <string, string>();
                    qryParams.Add("EventCalendarId", eventItem.EventCalendarId.ToString());

                    var pageCache = PageCache.Read(RockPage.PageId);
                    if (pageCache != null && pageCache.ParentPage != null && pageCache.ParentPage.ParentPage != null)
                    {
                        NavigateToPage(pageCache.ParentPage.ParentPage.Guid, qryParams);
                    }
                }
            }
        }
Example #8
0
        public void InheritedAttributes_SetAttributeOnParentEntity_SetsValueForChildEntity()
        {
            var rockContext          = new RockContext();
            var eventItemService     = new EventItemService(rockContext);
            var eventCalendarService = new EventCalendarItemService(rockContext);

            // Setting the value of an inherited Attribute should persist the value for the child entity.
            var eventA = eventItemService.Get(EventAGuid.AsGuid());

            eventA.LoadAttributes(rockContext);
            eventA.SetAttributeValue(InternalCalendarAttribute1Key, "xyzzy");

            // TODO: SaveAttributeValues does not correctly save inherited values.
            // It wrongly attributes them to the entity on which they are set rather than the inherited entity.
            eventA.SaveAttributeValues(rockContext);

            var calendarItemInternal = eventCalendarService.Get(EventACalendarInternalGuid.AsGuid());
            var calendarItemPublic   = eventCalendarService.Get(EventACalendarPublicGuid.AsGuid());

            calendarItemInternal.LoadAttributes();
            Assert.IsTrue(calendarItemInternal.AttributeValues[InternalCalendarAttribute1Key].Value == "xyzzy");
            calendarItemPublic.LoadAttributes();
            Assert.IsTrue(calendarItemPublic.AttributeValues[InternalCalendarAttribute1Key].Value == "xyzzy");
        }
Example #9
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click( object sender, EventArgs e )
        {
            ConnectionOpportunity connectionOpportunity = null;

            using ( RockContext rockContext = new RockContext() )
            {
                int? groupTypeId = ddlGroupType.SelectedValueAsInt();
                if ( groupTypeId.HasValue && GroupsState.Any( g => g.Group.GroupTypeId != groupTypeId.Value ) )
                {
                    var groupType = new GroupTypeService( rockContext ).Get( groupTypeId.Value );
                    if ( groupType != null )
                    {
                        nbInvalidGroupTypes.Text = string.Format( "<p>One or more of the selected groups is not a <strong>{0}</strong> type. Please select groups that have a group type of <strong>{0}</strong>.", groupType.Name );
                        nbInvalidGroupTypes.Visible = true;
                        return;
                    }
                }

                ConnectionOpportunityService connectionOpportunityService = new ConnectionOpportunityService( rockContext );
                EventCalendarItemService eventCalendarItemService = new EventCalendarItemService( rockContext );
                ConnectionWorkflowService connectionWorkflowService = new ConnectionWorkflowService( rockContext );
                ConnectionOpportunityConnectorGroupService connectionOpportunityConnectorGroupsService = new ConnectionOpportunityConnectorGroupService( rockContext );
                ConnectionOpportunityCampusService connectionOpportunityCampusService = new ConnectionOpportunityCampusService( rockContext );
                ConnectionOpportunityGroupService connectionOpportunityGroupService = new ConnectionOpportunityGroupService( rockContext );

                int connectionOpportunityId = hfConnectionOpportunityId.ValueAsInt();
                if ( connectionOpportunityId != 0 )
                {
                    connectionOpportunity = connectionOpportunityService
                        .Queryable( "ConnectionOpportunityGroups, ConnectionWorkflows" )
                        .Where( ei => ei.Id == connectionOpportunityId )
                        .FirstOrDefault();
                }

                if ( connectionOpportunity == null )
                {
                    connectionOpportunity = new ConnectionOpportunity();
                    connectionOpportunity.Name = string.Empty;
                    connectionOpportunity.ConnectionTypeId = PageParameter( "ConnectionTypeId" ).AsInteger();
                    connectionOpportunityService.Add( connectionOpportunity );

                }

                connectionOpportunity.Name = tbName.Text;
                connectionOpportunity.Description = tbDescription.Text;
                connectionOpportunity.IsActive = cbIsActive.Checked;
                connectionOpportunity.PublicName = tbPublicName.Text;
                connectionOpportunity.IconCssClass = tbIconCssClass.Text;
                connectionOpportunity.GroupTypeId = ddlGroupType.SelectedValue.AsInteger();
                connectionOpportunity.GroupMemberRoleId = ddlGroupRole.SelectedValue.AsInteger();
                connectionOpportunity.GroupMemberStatus = ddlGroupMemberStatus.SelectedValueAsEnum<GroupMemberStatus>();

                int? orphanedPhotoId = null;
                if ( imgupPhoto.BinaryFileId != null )
                {
                    if ( connectionOpportunity.PhotoId != imgupPhoto.BinaryFileId )
                    {
                        orphanedPhotoId = connectionOpportunity.PhotoId;
                    }
                    connectionOpportunity.PhotoId = imgupPhoto.BinaryFileId.Value;
                }

                // remove any workflows that removed in the UI
                var uiWorkflows = WorkflowsState.Where( w => w.ConnectionTypeId == null ).Select( l => l.Guid );
                foreach ( var connectionOpportunityWorkflow in connectionOpportunity.ConnectionWorkflows.Where( l => !uiWorkflows.Contains( l.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionWorkflows.Remove( connectionOpportunityWorkflow );
                    connectionWorkflowService.Delete( connectionOpportunityWorkflow );
                }

                // Add or Update workflows from the UI
                foreach ( ConnectionWorkflow connectionOpportunityWorkflowState in WorkflowsState.Where( w => w.ConnectionTypeId == null ) )
                {
                    ConnectionWorkflow connectionOpportunityWorkflow = connectionOpportunity.ConnectionWorkflows.Where( a => a.Guid == connectionOpportunityWorkflowState.Guid ).FirstOrDefault();
                    if ( connectionOpportunityWorkflow == null )
                    {
                        connectionOpportunityWorkflow = new ConnectionWorkflow();
                        connectionOpportunity.ConnectionWorkflows.Add( connectionOpportunityWorkflow );
                    }
                    connectionOpportunityWorkflow.CopyPropertiesFrom( connectionOpportunityWorkflowState );
                    connectionOpportunityWorkflow.ConnectionOpportunityId = connectionOpportunity.Id;
                }

                // remove any group campuses that removed in the UI
                var uiGroupCampuses = GroupCampusesState.Select( l => l.Guid );
                foreach ( var connectionOpportunityConnectorGroups in connectionOpportunity.ConnectionOpportunityConnectorGroups.Where( l => !uiGroupCampuses.Contains( l.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityConnectorGroups.Remove( connectionOpportunityConnectorGroups );
                    connectionOpportunityConnectorGroupsService.Delete( connectionOpportunityConnectorGroups );
                }

                // Add or Update group campuses from the UI
                foreach ( var connectionOpportunityConnectorGroupsState in GroupCampusesState )
                {
                    ConnectionOpportunityConnectorGroup connectionOpportunityConnectorGroups = connectionOpportunity.ConnectionOpportunityConnectorGroups.Where( a => a.Guid == connectionOpportunityConnectorGroupsState.Guid ).FirstOrDefault();
                    if ( connectionOpportunityConnectorGroups == null )
                    {
                        connectionOpportunityConnectorGroups = new ConnectionOpportunityConnectorGroup();
                        connectionOpportunity.ConnectionOpportunityConnectorGroups.Add( connectionOpportunityConnectorGroups );
                    }

                    connectionOpportunityConnectorGroups.CopyPropertiesFrom( connectionOpportunityConnectorGroupsState );
                }

                // remove any campuses that removed in the UI
                var uiCampuses = cblCampus.SelectedValuesAsInt;
                foreach ( var connectionOpportunityCampus in connectionOpportunity.ConnectionOpportunityCampuses.Where( c => !uiCampuses.Contains( c.CampusId ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityCampuses.Remove( connectionOpportunityCampus );
                    connectionOpportunityCampusService.Delete( connectionOpportunityCampus );
                }

                // Add or Update campuses from the UI
                foreach ( var campusId in uiCampuses )
                {
                    ConnectionOpportunityCampus connectionOpportunityCampus = connectionOpportunity.ConnectionOpportunityCampuses.Where( c => c.CampusId == campusId ).FirstOrDefault();
                    if ( connectionOpportunityCampus == null )
                    {
                        connectionOpportunityCampus = new ConnectionOpportunityCampus();
                        connectionOpportunity.ConnectionOpportunityCampuses.Add( connectionOpportunityCampus );
                    }

                    connectionOpportunityCampus.CampusId = campusId;
                }

                // Remove any groups that were removed in the UI
                var uiGroups = GroupsState.Select( r => r.Guid );
                foreach ( var connectionOpportunityGroup in connectionOpportunity.ConnectionOpportunityGroups.Where( r => !uiGroups.Contains( r.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityGroups.Remove( connectionOpportunityGroup );
                    connectionOpportunityGroupService.Delete( connectionOpportunityGroup );
                }

                // Add or Update groups from the UI
                foreach ( var connectionOpportunityGroupState in GroupsState )
                {
                    ConnectionOpportunityGroup connectionOpportunityGroup = connectionOpportunity.ConnectionOpportunityGroups.Where( a => a.Guid == connectionOpportunityGroupState.Guid ).FirstOrDefault();
                    if ( connectionOpportunityGroup == null )
                    {
                        connectionOpportunityGroup = new ConnectionOpportunityGroup();
                        connectionOpportunity.ConnectionOpportunityGroups.Add( connectionOpportunityGroup );
                    }

                    connectionOpportunityGroup.CopyPropertiesFrom( connectionOpportunityGroupState );
                }

                connectionOpportunity.LoadAttributes();
                Rock.Attribute.Helper.GetEditValues( phAttributes, connectionOpportunity );

                if ( !Page.IsValid )
                {
                    return;
                }

                if ( !connectionOpportunity.IsValid )
                {
                    // Controls will render the error messages
                    return;
                }

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction( () =>
                {
                    rockContext.SaveChanges();

                    connectionOpportunity.SaveAttributeValues( rockContext );

                    if ( orphanedPhotoId.HasValue )
                    {
                        BinaryFileService binaryFileService = new BinaryFileService( rockContext );
                        var binaryFile = binaryFileService.Get( orphanedPhotoId.Value );
                        if ( binaryFile != null )
                        {
                            string errorMessage;
                            if ( binaryFileService.CanDelete( binaryFile, out errorMessage ) )
                            {
                                binaryFileService.Delete( binaryFile );
                                rockContext.SaveChanges();
                            }
                        }
                    }
                } );

                var qryParams = new Dictionary<string, string>();
                qryParams["ConnectionTypeId"] = PageParameter( "ConnectionTypeId" );
                NavigateToParentPage( qryParams );
            }
        }
        /// <summary>
        /// Handles the Click event of the lbCalendarItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void lbCalendarItem_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var eventItem = new EventCalendarItemService( rockContext )
                    .Get( PageParameter( "EventItemId" ).AsInteger() );

                if ( eventItem != null )
                {
                    var qryParams = new Dictionary<string, string>();
                    qryParams.Add( "EventItemId", eventItem.Id.ToString() );
                    qryParams.Add( "EventCalendarId", eventItem.EventCalendarId.ToString() );
                    NavigateToParentPage( qryParams );
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the lbCalendarDetail control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void lbCalendarDetail_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                var eventItem = new EventCalendarItemService( rockContext )
                    .Get( PageParameter( "EventItemId" ).AsInteger() );

                if ( eventItem != null )
                {
                    var qryParams = new Dictionary<string, string>();
                    qryParams.Add( "EventCalendarId", eventItem.EventCalendarId.ToString() );

                    var pageCache = PageCache.Read( RockPage.PageId );
                    if ( pageCache != null && pageCache.ParentPage != null && pageCache.ParentPage.ParentPage != null )
                    {
                        NavigateToPage( pageCache.ParentPage.ParentPage.Guid, qryParams );
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// Syncs an eSpace event into Rock.
        /// </summary>
        /// <param name="eSpaceClient">The eSpace client</param>
        /// <param name="eSpaceEvent">The eSpace event</param>
        /// <param name="occurrencesFilter">The filter to use when syncing occurrences</param>
        /// <returns>The synced Rock event</returns>
        public static async Task SyncEvent(
            Client eSpaceClient,
            ESpace.Event eSpaceEvent,
            GetEventOccurrencesOptions occurrencesFilter,
            EventCalendarCache globalCalendar,
            EventCalendarCache publicCalendar,
            EventCalendarCache privateCalendar,
            string occurrenceApprovedAttributeKey
            )
        {
            using (var rockContext = new RockContext())
            {
                // Create our services
                var eventItemService           = new EventItemService(rockContext);
                var eventItemOccurrenceService = new EventItemOccurrenceService(rockContext);
                var eventItemAudienceService   = new EventItemAudienceService(rockContext);
                var scheduleService            = new ScheduleService(rockContext);
                var personService = new PersonService(rockContext);

                // Get or create the linked Rock event
                var rockEvent = eventItemService.GetOrCreateByForeignId(
                    "EventCalendarItems,EventItemOccurrences",
                    ForeignKey_eSpaceEventId,
                    eSpaceEvent.EventId.Value,
                    out var _
                    );

                // Track if we needed to update anything
                var changed = false;

                // Update the Name
                if (rockEvent.Name != eSpaceEvent.EventName)
                {
                    changed        = true;
                    rockEvent.Name = eSpaceEvent.EventName;
                }

                // Update the Active State
                var eSpaceEventIsActive = eSpaceEvent.Status != ESpaceStatus_Draft;
                if (rockEvent.IsActive != eSpaceEventIsActive)
                {
                    changed            = true;
                    rockEvent.IsActive = eSpaceEventIsActive;
                }

                // Update the Approval State
                var eSpaceEventIsApproved = eSpaceEvent.Status == ESpaceStatus_Approved;
                if (rockEvent.IsApproved != eSpaceEventIsApproved)
                {
                    changed = true;
                    rockEvent.IsApproved = eSpaceEventIsApproved;

                    if (eSpaceEventIsApproved)
                    {
                        rockEvent.ApprovedOnDateTime = DateTime.Now;
                    }
                    else
                    {
                        rockEvent.ApprovedOnDateTime = null;
                    }
                }

                // Update the Summary
                if (rockEvent.Summary != eSpaceEvent.Description)
                {
                    changed           = true;
                    rockEvent.Summary = eSpaceEvent.Description;
                }

                // Update the details Url
                var eSpaceEventPublicLink = eSpaceEvent.PublicLink?.ToString();
                if (rockEvent.DetailsUrl != eSpaceEventPublicLink)
                {
                    changed = true;
                    rockEvent.DetailsUrl = eSpaceEventPublicLink;
                }

                // Update the audiences
                var eSpaceCategories = MatchCategories(eSpaceEvent.Categories);


                // Check global calendar
                if (globalCalendar != null)
                {
                    rockEvent.AddToCalendar(globalCalendar, out var addedToCalendar);
                    changed = changed || addedToCalendar;
                }

                var eventCalendarItemService = new EventCalendarItemService(rockContext);

                // Check public calendar
                if (publicCalendar != null)
                {
                    if (eSpaceEvent.IsPublic ?? false)
                    {
                        rockEvent.AddToCalendar(publicCalendar, out var addedToCalendar);
                        changed = changed || addedToCalendar;
                    }
                    else
                    {
                        rockEvent.RemoveFromCalendar(eventCalendarItemService, publicCalendar, out var removedFromCalendar);
                        changed = changed || removedFromCalendar;
                    }
                }

                // Check private calendar
                if (privateCalendar != null)
                {
                    if (!(eSpaceEvent.IsPublic ?? false))
                    {
                        rockEvent.AddToCalendar(privateCalendar, out var addedToCalendar);
                        changed = changed || addedToCalendar;
                    }
                    else
                    {
                        rockEvent.RemoveFromCalendar(eventCalendarItemService, privateCalendar, out var removedFromCalendar);
                        changed = changed || removedFromCalendar;
                    }
                }

                // Fetch the occurrences for the event
                if (occurrencesFilter == null)
                {
                    occurrencesFilter = new GetEventOccurrencesOptions {
                        StartDate = DateTime.Now
                    }
                }
                ;
                occurrencesFilter.EventId = eSpaceEvent.EventId;
                var eSpaceEventOccurrences = await eSpaceClient.GetEventOccurrences(occurrencesFilter);

                // Calculate some stuff for the occurrences
                var campusLocations = MatchLocations(eSpaceEvent.IsOffSite ?? false ? eSpaceEvent.PublicLocations : eSpaceEvent.Locations);
                var contactPerson   = personService.FindPerson(eSpaceEvent.Contacts.FirstOrDefault());

                var firstESpaceOccurrence = eSpaceEventOccurrences.FirstOrDefault();
                if (firstESpaceOccurrence != null)
                {
                    // Update the Description
                    if (rockEvent.Description != firstESpaceOccurrence.PublicHtmlNotes)
                    {
                        rockEvent.Description = firstESpaceOccurrence.PublicHtmlNotes;
                        changed = true;
                    }
                }

                var syncedRockOccurrences = new List <EventItemOccurrence>();;
                var rockOccurrencesWithAttributeChanges = new List <EventItemOccurrence>();

                // Update each occurrence
                foreach (var eSpaceOccurrence in eSpaceEventOccurrences)
                {
                    foreach (var campusLocation in campusLocations)
                    {
                        var rockOccurrence = SyncOccurrence(eSpaceEvent, eSpaceOccurrence, rockEvent, campusLocation, contactPerson, occurrenceApprovedAttributeKey, out var occurrenceChanged, out var occurrenceAttributeChanged);
                        changed = changed || occurrenceChanged;
                        syncedRockOccurrences.Add(rockOccurrence);
                        if (occurrenceAttributeChanged)
                        {
                            rockOccurrencesWithAttributeChanges.Add(rockOccurrence);
                        }
                    }
                }

                // Remove any desynced occurrences
                var removedOccurrences = rockEvent.EventItemOccurrences.Except(syncedRockOccurrences).ToList();
                foreach (var occurrence in removedOccurrences)
                {
                    rockEvent.EventItemOccurrences.Remove(occurrence);
                    if (occurrence.Schedule != null)
                    {
                        scheduleService.Delete(occurrence.Schedule);
                        occurrence.Schedule = null;
                    }
                    eventItemOccurrenceService.Delete(occurrence);
                    changed = true;
                }

                // If anything was updated, save it
                if (changed)
                {
                    rockContext.SaveChanges();
                }

                // If any occurrences had attributes modified, save them
                foreach (var rockOccurrence in rockOccurrencesWithAttributeChanges)
                {
                    rockOccurrence.SaveAttributeValues();
                }
            }
        }
        /// <summary>
        /// Binds the event calendar items grid.
        /// </summary>
        protected void BindEventCalendarItemsGrid()
        {
            if (_eventCalendar != null)
            {
                pnlEventCalendarItems.Visible = true;

                var rockContext = new RockContext();

                EventCalendarItemService eventCalendarItemService = new EventCalendarItemService(rockContext);
                var qry = eventCalendarItemService
                          .Queryable("EventCalendar,EventItem.EventItemAudiences,EventItem.EventItemOccurrences.Schedule")
                          .Where(m =>
                                 m.EventItem != null &&
                                 m.EventCalendarId == _eventCalendar.Id);

                // Filter by Status
                string statusFilter = ddlStatus.SelectedValue;
                if (statusFilter == "Active")
                {
                    qry = qry
                          .Where(m => m.EventItem.IsActive);
                }
                else if (statusFilter == "Inactive")
                {
                    qry = qry
                          .Where(m => !m.EventItem.IsActive);
                }

                // Filter by Approval Status
                string approvalStatusFilter = ddlApprovalStatus.SelectedValue;
                if (approvalStatusFilter == "Approved")
                {
                    qry = qry
                          .Where(m => m.EventItem.IsApproved);
                }
                else if (approvalStatusFilter == "Not Approved")
                {
                    qry = qry
                          .Where(m => !m.EventItem.IsApproved);
                }

                // Filter by Campus
                List <int> campusIds = cblCampus.SelectedValuesAsInt;
                if (campusIds.Any())
                {
                    qry = qry
                          .Where(i =>
                                 i.EventItem.EventItemOccurrences
                                 .Any(c =>
                                      !c.CampusId.HasValue ||
                                      campusIds.Contains(c.CampusId.Value)));
                }

                // Filter query by any configured attribute filters
                if (AvailableAttributes != null && AvailableAttributes.Any())
                {
                    var attributeValueService = new AttributeValueService(rockContext);
                    var parameterExpression   = attributeValueService.ParameterExpression;

                    foreach (var attribute in AvailableAttributes)
                    {
                        var filterControl = phAttributeFilters.FindControl("filter_" + attribute.Id.ToString());
                        if (filterControl != null)
                        {
                            var filterValues = attribute.FieldType.Field.GetFilterValues(filterControl, attribute.QualifierValues, Rock.Reporting.FilterMode.SimpleFilter);
                            var expression   = attribute.FieldType.Field.AttributeFilterExpression(attribute.QualifierValues, filterValues, parameterExpression);
                            if (expression != null)
                            {
                                var attributeValues = attributeValueService
                                                      .Queryable()
                                                      .Where(v => v.Attribute.Id == attribute.Id);

                                attributeValues = attributeValues.Where(parameterExpression, expression, null);

                                qry = qry.Where(w => attributeValues.Select(v => v.EntityId).Contains(w.Id));
                            }
                        }
                    }
                }

                // Filter by Audience
                List <int> audiences = cblAudience.SelectedValuesAsInt;
                if (audiences.Any())
                {
                    qry = qry.Where(i => i.EventItem.EventItemAudiences
                                    .Any(c => audiences.Contains(c.DefinedValueId)));
                }

                SortProperty sortProperty = gEventCalendarItems.SortProperty;

                // Sort and query db
                List <EventCalendarItem> eventCalendarItems = null;
                if (sortProperty != null)
                {
                    // If sorting on date, wait until after checking to see if date range was specified
                    if (sortProperty.Property == "Date")
                    {
                        eventCalendarItems = qry.ToList();
                    }
                    else
                    {
                        eventCalendarItems = qry.Sort(sortProperty).ToList();
                    }
                }
                else
                {
                    eventCalendarItems = qry.OrderBy(a => a.EventItem.Name).ToList();
                }

                // Now that items have been loaded and ordered from db, calculate the next start date for each item
                var calendarItemsWithDates = eventCalendarItems
                                             .Select(i => new EventCalendarItemWithDates
                {
                    EventCalendarItem = i,
                    NextStartDateTime = i.EventItem.NextStartDateTime,
                })
                                             .ToList();

                var dateCol = gEventCalendarItems.Columns.OfType <BoundField>().Where(c => c.DataField == "Date").FirstOrDefault();

                // if a date range was specified, need to get all dates for items and filter based on any that have an occurrence withing the date range
                DateTime?lowerDateRange = drpDate.LowerValue;
                DateTime?upperDateRange = drpDate.UpperValue;
                if (lowerDateRange.HasValue || upperDateRange.HasValue)
                {
                    // If only one value was included, default the other to be a years difference
                    lowerDateRange = lowerDateRange ?? upperDateRange.Value.AddYears(-1).AddDays(1);
                    upperDateRange = upperDateRange ?? lowerDateRange.Value.AddYears(1).AddDays(-1);

                    // Get the start datetimes within the selected date range
                    calendarItemsWithDates.ForEach(i => i.StartDateTimes = i.EventCalendarItem.EventItem.GetStartTimes(lowerDateRange.Value, upperDateRange.Value.AddDays(1)));

                    // Filter out calendar items with no dates within range
                    calendarItemsWithDates = calendarItemsWithDates.Where(i => i.StartDateTimes.Any()).ToList();

                    // Update the Next Start Date to be the next date in range instead
                    dateCol.HeaderText = "Next Date In Range";
                    calendarItemsWithDates.ForEach(i => i.NextStartDateTime = i.StartDateTimes.Min());
                }
                else
                {
                    dateCol.HeaderText = "Next Start Date";
                }

                // Now sort on date if that is what was selected
                if (sortProperty != null && sortProperty.Property == "Date")
                {
                    if (sortProperty.Direction == SortDirection.Ascending)
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderBy(a => a.NextStartDateTime).ToList();
                    }
                    else
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderByDescending(a => a.NextStartDateTime).ToList();
                    }
                }

                // Save the calendar items to the grid's objectlist
                gEventCalendarItems.ObjectList = new Dictionary <string, object>();
                calendarItemsWithDates.ForEach(i => gEventCalendarItems.ObjectList.Add(i.EventCalendarItem.EventItem.Id.ToString(), i.EventCalendarItem));
                gEventCalendarItems.EntityTypeId = EntityTypeCache.Read("Rock.Model.EventCalendarItem").Id;

                gEventCalendarItems.DataSource = calendarItemsWithDates.Select(i => new
                {
                    Id          = i.EventCalendarItem.EventItem.Id,
                    Guid        = i.EventCalendarItem.EventItem.Guid,
                    Date        = i.NextStartDateTime.HasValue ? i.NextStartDateTime.Value.ToShortDateString() : "N/A",
                    Name        = i.EventCalendarItem.EventItem.Name,
                    Occurrences = campusIds.Any() ?
                                  i.EventCalendarItem.EventItem.EventItemOccurrences.Where(c => !c.CampusId.HasValue || campusIds.Contains(c.CampusId.Value)).Count() :
                                  i.EventCalendarItem.EventItem.EventItemOccurrences.Count(),
                    Calendar       = i.EventCalendarItem.EventItem.EventCalendarItems.ToList().Select(c => c.EventCalendar.Name).ToList().AsDelimited("<br>"),
                    Audience       = i.EventCalendarItem.EventItem.EventItemAudiences.ToList().Select(a => a.DefinedValue.Value).ToList().AsDelimited("<br>"),
                    Status         = i.EventCalendarItem.EventItem.IsActive ? "<span class='label label-success'>Active</span>" : "<span class='label label-default'>Inactive</span>",
                    ApprovalStatus = i.EventCalendarItem.EventItem.IsApproved ? "<span class='label label-info'>Approved</span>" : "<span class='label label-warning'>Not Approved</span>"
                }).ToList();

                gEventCalendarItems.DataBind();
            }
            else
            {
                pnlEventCalendarItems.Visible = false;
            }
        }
Example #14
0
        private void DisplayDetails()
        {
            RockContext rockContext = new RockContext();

            EventItemService eventItemService = new EventItemService(rockContext);
            var qry = eventItemService
                      .Queryable();

            // get the eventItem id if the event item is set via block attribute
            var eventItemAttGuid = GetAttributeValue("EventItem").AsGuid();
            int eventItemId      = qry.Where(i => i.Guid == eventItemAttGuid).Select(i => i.Id).FirstOrDefault();

            // get the eventItem id if the event item block attribute isn't set
            if (eventItemId == 0 && !string.IsNullOrWhiteSpace(PageParameter("EventItemId")))
            {
                eventItemId = Convert.ToInt32(PageParameter("EventItemId"));
            }
            if (eventItemId > 0)
            {
                /*var qry = eventItemService
                 *  .Queryable()
                 *  ;*/
                qry = qry.Where(i => i.Id == eventItemId);
            }
            else
            {
                // Get the Slug Attribute
                var slugAttribute = AttributeCache.Get(GetAttributeValue("URLSlugAttribute").AsGuid());

                // get the slug
                if (!string.IsNullOrWhiteSpace(PageParameter("URLSlug")) && slugAttribute != null)
                {
                    int slugAttributeId = slugAttribute.Id;
                    EventCalendarItemService eventCalendarItemService = new EventCalendarItemService(rockContext);
                    AttributeValueService    attributeValueService    = new AttributeValueService(rockContext);

                    var tmQry = qry.Join(eventCalendarItemService.Queryable(),
                                         ei => ei.Id,
                                         aci => aci.EventItemId,
                                         (ei, aci) => new { EventItem = ei, EventCalendarItem = aci }
                                         )
                                .Join(attributeValueService.Queryable(),
                                      ei => new { Id = ei.EventCalendarItem.Id, AttributeId = slugAttributeId },
                                      av => new { Id = av.EntityId ?? 0, AttributeId = av.AttributeId },
                                      (ei, av) => new { EventItem = ei.EventItem, EventCalendarItem = ei.EventCalendarItem, Slug = av });

                    string urlSlug = PageParameter("URLSlug");

                    tmQry = tmQry.Where(obj => obj.Slug.Value.Contains(urlSlug));

                    // The page parameter could contain something like 'camp' while the slug value list contains 'camp-freedom' so we need to double-check
                    // to make sure we have an exact match
                    qry = tmQry.ToList().AsQueryable().Where(obj => obj.Slug.Value.ToLower().Split('|').Contains(urlSlug.ToLower())).Select(obj => obj.EventItem);
                }
                else
                {
                    // If we don't have an eventItemId or slug we shouldn't get the first item in the database.  That would be . . . not good
                    qry = null;
                }
            }

            if (qry != null)
            {
                var eventItem = qry.FirstOrDefault();

                if (eventItem != null)
                {
                    // removing any occurrences that don't have a start time in the next twelve months
                    var occurrenceList = eventItem.EventItemOccurrences.ToList();
                    occurrenceList.RemoveAll(o => o.GetStartTimes(RockDateTime.Now, RockDateTime.Now.AddYears(1)).Count() == 0);

                    //Check for Campus Id Parameter
                    var campusId = PageParameter("CampusId").AsIntegerOrNull();
                    if (campusId.HasValue)
                    {
                        //check if there's a campus with this id.
                        var campus = CampusCache.Get(campusId.Value);
                        if (campus != null)
                        {
                            occurrenceList.RemoveAll(o => o.CampusId != null && o.CampusId != campus.Id);
                        }
                    }

                    //Check for Campus
                    var campusStr = PageParameter("Campus");
                    if (!string.IsNullOrEmpty(campusStr))
                    {
                        //check if there's a campus with this name.
                        var campus = CampusCache.All().Where(c => c.Name.ToLower().RemoveSpaces() == campusStr.ToLower().RemoveSpaces()).FirstOrDefault();
                        if (campus != null)
                        {
                            occurrenceList.RemoveAll(o => o.CampusId != null && o.CampusId != campus.Id);
                        }
                        else
                        {
                            // check one more time to see if there's a campus slug that matches
                            campus = CampusCache.All().Where(c => c.AttributeValues["Slug"].ToString() == campusStr.ToLower()).FirstOrDefault();
                            if (campus != null)
                            {
                                occurrenceList.RemoveAll(o => o.CampusId != null && o.CampusId != campus.Id);
                            }
                        }
                    }

                    eventItem.EventItemOccurrences = occurrenceList.OrderBy(o => o.NextStartDateTime.HasValue ? o.NextStartDateTime : DateTime.Now).ToList();

                    var mergeFields = new Dictionary <string, object>();
                    mergeFields.Add("RegistrationPage", LinkedPageRoute("RegistrationPage"));

                    var campusEntityType = EntityTypeCache.Get("Rock.Model.Campus");
                    var contextCampus    = RockPage.GetCurrentContext(campusEntityType) as Campus;

                    if (contextCampus != null)
                    {
                        mergeFields.Add("CampusContext", contextCampus);
                    }

                    // determine registration status (Register, Full, or Join Wait List) for each unique registration instance
                    Dictionary <int, string> registrationStatusLabels = new Dictionary <int, string>();
                    foreach (var occurance in eventItem.EventItemOccurrences)
                    {
                        foreach (var registrationInstance in occurance.Linkages.Select(a => a.RegistrationInstance).Distinct().ToList())
                        {
                            if (registrationStatusLabels.ContainsKey(registrationInstance.Id))
                            {
                                continue;
                            }
                            int?maxRegistrantCount       = 0;
                            var currentRegistrationCount = 0;

                            if (registrationInstance != null)
                            {
                                if (registrationInstance.MaxAttendees != 0)
                                {
                                    maxRegistrantCount = registrationInstance.MaxAttendees;
                                }
                            }


                            int?registrationSpotsAvailable = null;
                            if (maxRegistrantCount.HasValue && maxRegistrantCount != 0)
                            {
                                currentRegistrationCount = new RegistrationRegistrantService(rockContext).Queryable().AsNoTracking()
                                                           .Where(r =>
                                                                  r.Registration.RegistrationInstanceId == registrationInstance.Id &&
                                                                  r.OnWaitList == false)
                                                           .Count();
                                registrationSpotsAvailable = maxRegistrantCount - currentRegistrationCount;
                            }

                            string registrationStatusLabel = "Register";

                            if (registrationSpotsAvailable.HasValue && registrationSpotsAvailable.Value < 1)
                            {
                                if (registrationInstance.RegistrationTemplate.WaitListEnabled)
                                {
                                    registrationStatusLabel = "Join Wait List";
                                }
                                else
                                {
                                    registrationStatusLabel = "Full";
                                }
                            }

                            registrationStatusLabels.Add(registrationInstance.Id, registrationStatusLabel);
                        }
                    }

                    // Status of each registration instance
                    mergeFields.Add("RegistrationStatusLabels", registrationStatusLabels);

                    mergeFields.Add("Event", eventItem);
                    mergeFields.Add("CurrentPerson", CurrentPerson);

                    lOutput.Text = GetAttributeValue("LavaTemplate").ResolveMergeFields(mergeFields);

                    if (GetAttributeValue("SetPageTitle").AsBoolean())
                    {
                        string pageTitle = eventItem != null ? eventItem.Name : "Event";
                        RockPage.PageTitle    = pageTitle;
                        RockPage.BrowserTitle = String.Format("{0} | {1}", pageTitle, RockPage.Site.Name);
                        RockPage.Header.Title = String.Format("{0} | {1}", pageTitle, RockPage.Site.Name);
                    }
                }
                else
                {
                    lOutput.Text = EventNotFoundLava();
                }
            }
            else
            {
                lOutput.Text = EventNotFoundLava();
            }
        }
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click( object sender, EventArgs e )
        {
            ConnectionOpportunity connectionOpportunity = null;

            using ( RockContext rockContext = new RockContext() )
            {
                if ( !ValidPlacementGroups() )
                {
                    return;
                }

                ConnectionOpportunityService connectionOpportunityService = new ConnectionOpportunityService( rockContext );
                EventCalendarItemService eventCalendarItemService = new EventCalendarItemService( rockContext );
                ConnectionWorkflowService connectionWorkflowService = new ConnectionWorkflowService( rockContext );
                ConnectionRequestWorkflowService connectionRequestWorkflowService = new ConnectionRequestWorkflowService( rockContext );
                ConnectionOpportunityConnectorGroupService connectionOpportunityConnectorGroupsService = new ConnectionOpportunityConnectorGroupService( rockContext );
                ConnectionOpportunityCampusService connectionOpportunityCampusService = new ConnectionOpportunityCampusService( rockContext );
                ConnectionOpportunityGroupConfigService connectionOpportunityGroupConfigService = new ConnectionOpportunityGroupConfigService( rockContext );
                ConnectionOpportunityGroupService connectionOpportunityGroupService = new ConnectionOpportunityGroupService( rockContext );

                int connectionOpportunityId = hfConnectionOpportunityId.ValueAsInt();
                if ( connectionOpportunityId != 0 )
                {
                    connectionOpportunity = connectionOpportunityService
                        .Queryable( "ConnectionOpportunityGroups, ConnectionWorkflows" )
                        .Where( ei => ei.Id == connectionOpportunityId )
                        .FirstOrDefault();
                }

                if ( connectionOpportunity == null )
                {
                    connectionOpportunity = new ConnectionOpportunity();
                    connectionOpportunity.Name = string.Empty;
                    connectionOpportunity.ConnectionTypeId = PageParameter( "ConnectionTypeId" ).AsInteger();
                    connectionOpportunityService.Add( connectionOpportunity );
                }

                connectionOpportunity.Name = tbName.Text;
                connectionOpportunity.Summary = htmlSummary.Text;
                connectionOpportunity.Description = htmlDescription.Text;
                connectionOpportunity.IsActive = cbIsActive.Checked;
                connectionOpportunity.PublicName = tbPublicName.Text;
                connectionOpportunity.IconCssClass = tbIconCssClass.Text;

                int? orphanedPhotoId = null;
                if ( imgupPhoto.BinaryFileId != null )
                {
                    if ( connectionOpportunity.PhotoId != imgupPhoto.BinaryFileId )
                    {
                        orphanedPhotoId = connectionOpportunity.PhotoId;
                    }
                    connectionOpportunity.PhotoId = imgupPhoto.BinaryFileId.Value;
                }

                // remove any workflows that removed in the UI
                var uiWorkflows = WorkflowsState.Where( w => w.ConnectionTypeId == null ).Select( l => l.Guid );
                foreach ( var connectionWorkflow in connectionOpportunity.ConnectionWorkflows.Where( l => !uiWorkflows.Contains( l.Guid ) ).ToList() )
                {
                    foreach( var requestWorkflow in connectionRequestWorkflowService.Queryable()
                        .Where( w => w.ConnectionWorkflowId == connectionWorkflow.Id ) )
                    {
                        connectionRequestWorkflowService.Delete( requestWorkflow );
                    }

                    connectionOpportunity.ConnectionWorkflows.Remove( connectionWorkflow );
                    connectionWorkflowService.Delete( connectionWorkflow );
                }

                // Add or Update workflows from the UI
                foreach ( var workflowTypeStateObj in WorkflowsState.Where( w => w.ConnectionTypeId == null ) )
                {
                    ConnectionWorkflow connectionOpportunityWorkflow = connectionOpportunity.ConnectionWorkflows.Where( a => a.Guid == workflowTypeStateObj.Guid ).FirstOrDefault();
                    if ( connectionOpportunityWorkflow == null )
                    {
                        connectionOpportunityWorkflow = new ConnectionWorkflow();
                        connectionOpportunity.ConnectionWorkflows.Add( connectionOpportunityWorkflow );
                    }
                    connectionOpportunityWorkflow.Id = workflowTypeStateObj.Id;
                    connectionOpportunityWorkflow.Guid = workflowTypeStateObj.Guid;
                    connectionOpportunityWorkflow.ConnectionTypeId = workflowTypeStateObj.ConnectionTypeId;
                    connectionOpportunityWorkflow.WorkflowTypeId = workflowTypeStateObj.WorkflowTypeId;
                    connectionOpportunityWorkflow.TriggerType = workflowTypeStateObj.TriggerType;
                    connectionOpportunityWorkflow.QualifierValue = workflowTypeStateObj.QualifierValue;
                    connectionOpportunityWorkflow.ConnectionOpportunityId = connectionOpportunity.Id;
                }

                // remove any group campuses that removed in the UI
                var uiConnectorGroups = ConnectorGroupsState.Select( l => l.Guid );
                foreach ( var connectionOpportunityConnectorGroups in connectionOpportunity.ConnectionOpportunityConnectorGroups.Where( l => !uiConnectorGroups.Contains( l.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityConnectorGroups.Remove( connectionOpportunityConnectorGroups );
                    connectionOpportunityConnectorGroupsService.Delete( connectionOpportunityConnectorGroups );
                }

                // Add or Update group campuses from the UI
                foreach ( var groupStateObj in ConnectorGroupsState )
                {
                    ConnectionOpportunityConnectorGroup connectionOpportunityConnectorGroup = connectionOpportunity.ConnectionOpportunityConnectorGroups.Where( a => a.Guid == groupStateObj.Guid ).FirstOrDefault();
                    if ( connectionOpportunityConnectorGroup == null )
                    {
                        connectionOpportunityConnectorGroup = new ConnectionOpportunityConnectorGroup();
                        connectionOpportunity.ConnectionOpportunityConnectorGroups.Add( connectionOpportunityConnectorGroup );
                    }

                    connectionOpportunityConnectorGroup.CampusId = groupStateObj.CampusId;
                    connectionOpportunityConnectorGroup.ConnectorGroupId = groupStateObj.GroupId;
                    connectionOpportunityConnectorGroup.ConnectionOpportunityId = connectionOpportunity.Id;
                }

                // remove any campuses that removed in the UI
                var uiCampuses = cblSelectedItemsAsInt( cblCampus );
                foreach ( var connectionOpportunityCampus in connectionOpportunity.ConnectionOpportunityCampuses.Where( c => !uiCampuses.Contains( c.CampusId ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityCampuses.Remove( connectionOpportunityCampus );
                    connectionOpportunityCampusService.Delete( connectionOpportunityCampus );
                }

                // Add or Update campuses from the UI
                foreach ( var campusId in uiCampuses )
                {
                    ConnectionOpportunityCampus connectionOpportunityCampus = connectionOpportunity.ConnectionOpportunityCampuses.Where( c => c.CampusId == campusId ).FirstOrDefault();
                    if ( connectionOpportunityCampus == null )
                    {
                        connectionOpportunityCampus = new ConnectionOpportunityCampus();
                        connectionOpportunity.ConnectionOpportunityCampuses.Add( connectionOpportunityCampus );
                    }

                    connectionOpportunityCampus.CampusId = campusId;
                    connectionOpportunityCampus.DefaultConnectorPersonAliasId = DefaultConnectors.ContainsKey( campusId ) ? DefaultConnectors[campusId] : (int?)null;
                }

                // remove any group configs that were removed in the UI
                var uiGroupConfigs = GroupConfigsState.Select( r => r.Guid );
                foreach ( var connectionOpportunityGroupConfig in connectionOpportunity.ConnectionOpportunityGroupConfigs.Where( r => !uiGroupConfigs.Contains( r.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityGroupConfigs.Remove( connectionOpportunityGroupConfig );
                    connectionOpportunityGroupConfigService.Delete( connectionOpportunityGroupConfig );
                }

                // Add or Update group configs from the UI
                foreach ( var groupConfigStateObj in GroupConfigsState )
                {
                    ConnectionOpportunityGroupConfig connectionOpportunityGroupConfig = connectionOpportunity.ConnectionOpportunityGroupConfigs.Where( a => a.Guid == groupConfigStateObj.Guid ).FirstOrDefault();
                    if ( connectionOpportunityGroupConfig == null )
                    {
                        connectionOpportunityGroupConfig = new ConnectionOpportunityGroupConfig();
                        connectionOpportunity.ConnectionOpportunityGroupConfigs.Add( connectionOpportunityGroupConfig );
                    }

                    connectionOpportunityGroupConfig.GroupTypeId = groupConfigStateObj.GroupTypeId;
                    connectionOpportunityGroupConfig.GroupMemberRoleId = groupConfigStateObj.GroupMemberRoleId;
                    connectionOpportunityGroupConfig.GroupMemberStatus = groupConfigStateObj.GroupMemberStatus;
                    connectionOpportunityGroupConfig.UseAllGroupsOfType = groupConfigStateObj.UseAllGroupsOfType;

                    connectionOpportunityGroupConfig.ConnectionOpportunityId = connectionOpportunity.Id;
                }

                // Remove any groups that were removed in the UI
                var uiGroups = GroupsState.Select( r => r.Guid );
                foreach ( var connectionOpportunityGroup in connectionOpportunity.ConnectionOpportunityGroups.Where( r => !uiGroups.Contains( r.Guid ) ).ToList() )
                {
                    connectionOpportunity.ConnectionOpportunityGroups.Remove( connectionOpportunityGroup );
                    connectionOpportunityGroupService.Delete( connectionOpportunityGroup );
                }

                // Add or Update groups from the UI
                foreach ( var groupStateObj in GroupsState )
                {
                    ConnectionOpportunityGroup connectionOpportunityGroup = connectionOpportunity.ConnectionOpportunityGroups.Where( a => a.Guid == groupStateObj.Guid ).FirstOrDefault();
                    if ( connectionOpportunityGroup == null )
                    {
                        connectionOpportunityGroup = new ConnectionOpportunityGroup();
                        connectionOpportunity.ConnectionOpportunityGroups.Add( connectionOpportunityGroup );
                    }

                    connectionOpportunityGroup.GroupId = groupStateObj.GroupId;
                    connectionOpportunityGroup.ConnectionOpportunityId = connectionOpportunity.Id;
                }

                connectionOpportunity.LoadAttributes();
                Rock.Attribute.Helper.GetEditValues( phAttributes, connectionOpportunity );

                if ( !Page.IsValid )
                {
                    return;
                }

                if ( !connectionOpportunity.IsValid )
                {
                    // Controls will render the error messages
                    return;
                }

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction( () =>
                {
                    rockContext.SaveChanges();

                    connectionOpportunity.SaveAttributeValues( rockContext );

                    if ( orphanedPhotoId.HasValue )
                    {
                        BinaryFileService binaryFileService = new BinaryFileService( rockContext );
                        var binaryFile = binaryFileService.Get( orphanedPhotoId.Value );
                        if ( binaryFile != null )
                        {
                            string errorMessage;
                            if ( binaryFileService.CanDelete( binaryFile, out errorMessage ) )
                            {
                                binaryFileService.Delete( binaryFile );
                                rockContext.SaveChanges();
                            }
                        }
                    }
                } );

                ConnectionWorkflowService.FlushCachedTriggers();

                var qryParams = new Dictionary<string, string>();
                qryParams["ConnectionTypeId"] = PageParameter( "ConnectionTypeId" );
                NavigateToParentPage( qryParams );
            }
        }
        /// <summary>
        /// Binds the event calendar items grid.
        /// </summary>
        protected void BindEventCalendarItemsGrid()
        {
            if ( _eventCalendar != null )
            {
                pnlEventCalendarItems.Visible = true;

                var rockContext = new RockContext();

                EventCalendarItemService eventCalendarItemService = new EventCalendarItemService( rockContext );
                var qry = eventCalendarItemService
                    .Queryable( "EventCalendar,EventItem.EventItemAudiences,EventItem.EventItemOccurrences.Schedule" )
                    .Where( m =>
                        m.EventItem != null &&
                        m.EventCalendarId == _eventCalendar.Id );

                // Filter by Status
                string statusFilter = ddlStatus.SelectedValue;
                if ( statusFilter == "Active" )
                {
                    qry = qry
                        .Where( m => m.EventItem.IsActive );
                }
                else if ( statusFilter == "Inactive" )
                {
                    qry = qry
                        .Where( m => !m.EventItem.IsActive );
                }

                // Filter by Approval Status
                string approvalStatusFilter = ddlApprovalStatus.SelectedValue;
                if ( approvalStatusFilter == "Approved" )
                {
                    qry = qry
                        .Where( m => m.EventItem.IsApproved );
                }
                else if ( approvalStatusFilter == "Not Approved" )
                {
                    qry = qry
                        .Where( m => !m.EventItem.IsApproved );
                }

                // Filter by Campus
                List<int> campusIds = cblCampus.SelectedValuesAsInt;
                if ( campusIds.Any() )
                {
                    qry = qry
                        .Where( i =>
                            i.EventItem.EventItemOccurrences
                                .Any( c =>
                                    !c.CampusId.HasValue ||
                                    campusIds.Contains( c.CampusId.Value ) ) );
                }

                // Filter query by any configured attribute filters
                if ( AvailableAttributes != null && AvailableAttributes.Any() )
                {
                    var attributeValueService = new AttributeValueService( rockContext );
                    var parameterExpression = attributeValueService.ParameterExpression;

                    foreach ( var attribute in AvailableAttributes )
                    {
                        var filterControl = phAttributeFilters.FindControl( "filter_" + attribute.Id.ToString() );
                        if ( filterControl != null )
                        {
                            var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues, Rock.Reporting.FilterMode.SimpleFilter );
                            var expression = attribute.FieldType.Field.AttributeFilterExpression( attribute.QualifierValues, filterValues, parameterExpression );
                            if ( expression != null )
                            {
                                var attributeValues = attributeValueService
                                    .Queryable()
                                    .Where( v => v.Attribute.Id == attribute.Id );

                                attributeValues = attributeValues.Where( parameterExpression, expression, null );

                                qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) );
                            }
                        }
                    }
                }

                // Filter by Audience
                List<int> audiences = cblAudience.SelectedValuesAsInt;
                if ( audiences.Any() )
                {
                    qry = qry.Where( i => i.EventItem.EventItemAudiences
                        .Any( c => audiences.Contains( c.DefinedValueId ) ) );
                }

                SortProperty sortProperty = gEventCalendarItems.SortProperty;

                // Sort and query db
                List<EventCalendarItem> eventCalendarItems = null;
                if ( sortProperty != null )
                {
                    // If sorting on date, wait until after checking to see if date range was specified
                    if ( sortProperty.Property == "Date" )
                    {
                        eventCalendarItems = qry.ToList();
                    }
                    else
                    {
                        eventCalendarItems = qry.Sort( sortProperty ).ToList();
                    }
                }
                else
                {
                    eventCalendarItems = qry.OrderBy( a => a.EventItem.Name ).ToList();
                }

                // Now that items have been loaded and ordered from db, calculate the next start date for each item
                var calendarItemsWithDates = eventCalendarItems
                    .Select( i => new EventCalendarItemWithDates
                    {
                        EventCalendarItem = i,
                        NextStartDateTime = i.EventItem.NextStartDateTime,
                    } )
                    .ToList();

                var dateCol = gEventCalendarItems.Columns.OfType<BoundField>().Where( c => c.DataField == "Date" ).FirstOrDefault();

                // if a date range was specified, need to get all dates for items and filter based on any that have an occurrence withing the date range
                DateTime? lowerDateRange = drpDate.LowerValue;
                DateTime? upperDateRange = drpDate.UpperValue;
                if ( lowerDateRange.HasValue || upperDateRange.HasValue )
                {
                    // If only one value was included, default the other to be a years difference
                    lowerDateRange = lowerDateRange ?? upperDateRange.Value.AddYears( -1 ).AddDays( 1 );
                    upperDateRange = upperDateRange ?? lowerDateRange.Value.AddYears( 1 ).AddDays( -1 );

                    // Get the start datetimes within the selected date range
                    calendarItemsWithDates.ForEach( i => i.StartDateTimes = i.EventCalendarItem.EventItem.GetStartTimes( lowerDateRange.Value, upperDateRange.Value.AddDays( 1 ) ) );

                    // Filter out calendar items with no dates within range
                    calendarItemsWithDates = calendarItemsWithDates.Where( i => i.StartDateTimes.Any() ).ToList();

                    // Update the Next Start Date to be the next date in range instead
                    dateCol.HeaderText = "Next Date In Range";
                    calendarItemsWithDates.ForEach( i => i.NextStartDateTime = i.StartDateTimes.Min() );
                }
                else
                {
                    dateCol.HeaderText = "Next Start Date";
                }

                // Now sort on date if that is what was selected
                if ( sortProperty != null && sortProperty.Property == "Date" )
                {
                    if ( sortProperty.Direction == SortDirection.Ascending )
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderBy( a => a.NextStartDateTime ).ToList();
                    }
                    else
                    {
                        calendarItemsWithDates = calendarItemsWithDates.OrderByDescending( a => a.NextStartDateTime ).ToList();
                    }
                }

                // Save the calendar items to the grid's objectlist
                gEventCalendarItems.ObjectList = new Dictionary<string, object>();
                calendarItemsWithDates.ForEach( i => gEventCalendarItems.ObjectList.Add( i.EventCalendarItem.EventItem.Id.ToString(), i.EventCalendarItem ) );
                gEventCalendarItems.EntityTypeId = EntityTypeCache.Read( "Rock.Model.EventCalendarItem" ).Id;

                gEventCalendarItems.DataSource = calendarItemsWithDates.Select( i => new
                {
                    Id = i.EventCalendarItem.EventItem.Id,
                    Guid = i.EventCalendarItem.EventItem.Guid,
                    Date = i.NextStartDateTime.HasValue ? i.NextStartDateTime.Value.ToShortDateString() : "N/A",
                    Name = i.EventCalendarItem.EventItem.Name,
                    Occurrences = campusIds.Any() ?
                        i.EventCalendarItem.EventItem.EventItemOccurrences.Where( c => !c.CampusId.HasValue || campusIds.Contains( c.CampusId.Value ) ).Count() :
                        i.EventCalendarItem.EventItem.EventItemOccurrences.Count(),
                    Calendar = i.EventCalendarItem.EventItem.EventCalendarItems.ToList().Select( c => c.EventCalendar.Name ).ToList().AsDelimited( "<br>" ),
                    Audience = i.EventCalendarItem.EventItem.EventItemAudiences.ToList().Select( a => a.DefinedValue.Value ).ToList().AsDelimited( "<br>" ),
                    Status = i.EventCalendarItem.EventItem.IsActive ? "<span class='label label-success'>Active</span>" : "<span class='label label-default'>Inactive</span>",
                    ApprovalStatus = i.EventCalendarItem.EventItem.IsApproved ? "<span class='label label-info'>Approved</span>" : "<span class='label label-warning'>Not Approved</span>"
                } ).ToList();

                gEventCalendarItems.DataBind();
            }
            else
            {
                pnlEventCalendarItems.Visible = false;
            }
        }
Example #17
0
    /// <summary>
    /// Handles the Load event of the Page control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected void Page_Load(object sender, EventArgs e)
    {
        // Jeremy Weatherford [email protected]
        // build a database table of shortlinks based on
        // - a Google Sheet with custom links
        // - Events and Groups with a ShortURL attribute (space-delimited for multiple entries)
        // - Posts get /posts/title (canonicalized title)
        // - Messages get /messages/title

        // these shortlinks are used by Http404Error.aspx.cs to redirect

        bool debug = true;

        try
        {
            Dictionary <string, string> links = new Dictionary <string, string>();
            List <string> duplicates          = new List <string>();

            var rockContext = new RockContext();

            // fetch Google Sheet for custom shortlinks
            string sheetURL = "https://docs.google.com/spreadsheets/d/1Tc7E8tQ6wJjauYBKwDh1nOsfoVGK4zGci16tE91rp0U/export?format=csv";
            string csv      = new WebClient().DownloadString(sheetURL);

            bool first = true;
            foreach (string line in csv.Split('\n'))
            {
                if (first)
                {
                    first = false; continue;
                }
                var    fields = line.Split(',');
                string link = fields[0].Trim(), url = fields[1].Trim();

                if (links.ContainsKey(link))
                {
                    duplicates.Add(link + " duplicated by Google Sheet " + url);
                }
                else
                {
                    links.Add(link, url);
                }
            }
            d("loaded " + links.Keys.Count() + " links from Google Sheets");

            // iterate Events with ShortURL attribute
            var attrs = new AttributeValueService(rockContext).Queryable()
                        .Where(a => a.Attribute.Key == "ShortURL")
                        .Where(a => a.Attribute.EntityTypeQualifierColumn == "EventCalendarId");
            foreach (var attr in attrs)
            {
                string linkText = attr.Value.Trim();
                int    id       = attr.EntityId.Value;
                var    item     = new EventCalendarItemService(new RockContext()).Queryable()
                                  .FirstOrDefault(i => i.Id == id);
                if (item != null && linkText != "")
                {
                    string url = "/page/505?EventItemId=" + item.EventItemId;

                    foreach (string s in linkText.Split(' '))
                    {
                        string link = s;
                        if (link[0] != '/')
                        {
                            link = '/' + link;
                        }

                        if (links.ContainsKey(link))
                        {
                            duplicates.Add(link + " duplicated by Event " + id); // how to get event name?
                        }
                        else
                        {
                            links.Add(link, url);
                        }
                    }
                }
            }

            // iterate Messages
            var messages = new ContentChannelItemService(rockContext).Queryable()
                           .Where(i => i.ContentChannelId == 5);
            foreach (var item in messages)
            {
                string link = "/messages/" + canonicalize(item.Title);
                if (links.ContainsKey(link))
                {
                    duplicates.Add(link + " duplicated by Message " + item.Id + ": " + item.Title);
                }
                else
                {
                    string target = "/Page/498?Item=" + item.Id;
                    links.Add(link, target);
                }
            }

            // iterate Posts
            var posts = new ContentChannelItemService(rockContext).Queryable()
                        .Where(i => i.ContentChannelId == 3);
            foreach (var item in posts)
            {
                string link = "/posts/" + canonicalize(item.Title);
                if (links.ContainsKey(link))
                {
                    duplicates.Add(link + " duplicated by Post " + item.Id + ": " + item.Title);
                }
                else
                {
                    string target = "/Page/499?Item=" + item.Id;
                    links.Add(link, target);
                }
            }

            // show error messages
            d("<p>");
            foreach (string msg in duplicates)
            {
                d("<font color=#f00>" + msg + "</font>");
            }
            d("<p>");

            d(links.Keys.Count() + " total links");

            // create BRShortLinks table if not exists
            var query = "IF NOT EXISTS (SELECT name FROM sysobjects WHERE name = 'BRShortLinks') " +
                        "CREATE TABLE BRShortLinks(link nvarchar(250), url nvarchar(1024)," +
                        "CONSTRAINT PK_BRShortLinks_Link PRIMARY KEY CLUSTERED (link))";
            DbService.ExecuteScaler(query);

            // pull existing shortlinks and compare
            List <string> deletes = new List <string>();
            List <string> adds    = links.Keys.ToList();

            // iterate existing links and itemize changes
            var table = DbService.GetDataTable("SELECT link,url FROM BRShortLinks", CommandType.Text, null);
            d(table.Rows.Count + " existing links in DB");
            foreach (DataRow row in table.Rows)
            {
                string link = row[0].ToString(), url = row[1].ToString();
                if (!links.ContainsKey(link))
                {
                    deletes.Add(link);
                }
                else if (links[link] == url)
                {
                    // no changes needed
                    adds.Remove(link);
                }
            }

            // update table, log changes
            foreach (string link in adds)
            {
                var p = new Dictionary <string, object>();
                p.Add("@link", link.ToLower());
                p.Add("@url", links[link]);
                int rows = DbService.ExecuteCommand("UPDATE BRShortLinks set [url]=@url WHERE [link]=@link;" +
                                                    "if @@ROWCOUNT = 0 INSERT INTO BRShortLinks ([link],[url]) VALUES (@link, @url)",
                                                    CommandType.Text, p, null);
                if (debug)
                {
                    d("inserting " + link + ": " + rows + " rows");
                }
            }

            foreach (string link in deletes)
            {
                var p = new Dictionary <string, object>();
                p.Add("@link", link);
                DbService.ExecuteCommand("DELETE FROM BRShortLinks WHERE [link]=@link",
                                         CommandType.Text, p, null);
                if (debug)
                {
                    d("deleting " + link);
                }
            }

            d(adds.Count + " links added/updated, " + deletes.Count() + " links deleted");

            d("<p>");
            // debug dump of shortlink table
            foreach (var link in links.OrderBy(x => x.Key))
            {
                d(link.Key + " -> " + link.Value);
            }

            // pet the watchdog
            var res = new WebClient().DownloadString("http://zenithav.net/watchdog.php?key=BRShortLinks" + Environment.MachineName);
        }
        catch (Exception e2)
        {
            d(e2.Message);
        }
    }
Example #18
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            EventItem eventItem = null;

            using (var rockContext = new RockContext())
            {
                var validationMessages = new List <string>();

                var eventItemService         = new EventItemService(rockContext);
                var eventCalendarItemService = new EventCalendarItemService(rockContext);
                var eventItemAudienceService = new EventItemAudienceService(rockContext);

                int eventItemId = hfEventItemId.ValueAsInt();
                if (eventItemId != 0)
                {
                    eventItem = eventItemService
                                .Queryable("EventItemAudiences,EventItemOccurrences.Linkages,EventItemOccurrences")
                                .Where(i => i.Id == eventItemId)
                                .FirstOrDefault();
                }

                if (eventItem == null)
                {
                    eventItem = new EventItem();
                    eventItemService.Add(eventItem);
                }

                eventItem.Name     = tbName.Text;
                eventItem.IsActive = cbIsActive.Checked;

                if (!eventItem.IsApproved && cbIsApproved.Checked)
                {
                    eventItem.ApprovedByPersonAliasId = CurrentPersonAliasId;
                    eventItem.ApprovedOnDateTime      = RockDateTime.Now;
                }
                eventItem.IsApproved = cbIsApproved.Checked;
                if (!eventItem.IsApproved)
                {
                    eventItem.ApprovedByPersonAliasId = null;
                    eventItem.ApprovedByPersonAlias   = null;
                    eventItem.ApprovedOnDateTime      = null;
                }
                eventItem.Description = htmlDescription.Text;
                eventItem.Summary     = tbSummary.Text;
                eventItem.DetailsUrl  = tbDetailUrl.Text;

                int?orphanedImageId = null;
                if (eventItem.PhotoId != imgupPhoto.BinaryFileId)
                {
                    orphanedImageId   = eventItem.PhotoId;
                    eventItem.PhotoId = imgupPhoto.BinaryFileId;
                }

                // Remove any audiences that were removed in the UI
                foreach (var eventItemAudience in eventItem.EventItemAudiences.Where(r => !AudiencesState.Contains(r.DefinedValueId)).ToList())
                {
                    eventItem.EventItemAudiences.Remove(eventItemAudience);
                    eventItemAudienceService.Delete(eventItemAudience);
                }

                // Add or Update audiences from the UI
                foreach (int audienceId in AudiencesState)
                {
                    EventItemAudience eventItemAudience = eventItem.EventItemAudiences.Where(a => a.DefinedValueId == audienceId).FirstOrDefault();
                    if (eventItemAudience == null)
                    {
                        eventItemAudience = new EventItemAudience();
                        eventItemAudience.DefinedValueId = audienceId;
                        eventItem.EventItemAudiences.Add(eventItemAudience);
                    }
                }

                // remove any calendar items that removed in the UI
                var calendarIds = new List <int>();
                calendarIds.AddRange(cblCalendars.SelectedValuesAsInt);
                var uiCalendarGuids = ItemsState.Where(i => calendarIds.Contains(i.EventCalendarId)).Select(a => a.Guid);
                foreach (var eventCalendarItem in eventItem.EventCalendarItems.Where(a => !uiCalendarGuids.Contains(a.Guid)).ToList())
                {
                    // Make sure user is authorized to remove calendar (they may not have seen every calendar due to security)
                    if (UserCanEdit || eventCalendarItem.EventCalendar.IsAuthorized(Authorization.EDIT, CurrentPerson))
                    {
                        eventItem.EventCalendarItems.Remove(eventCalendarItem);
                        eventCalendarItemService.Delete(eventCalendarItem);
                    }
                }

                // Add or Update calendar items from the UI
                foreach (var calendar in ItemsState.Where(i => calendarIds.Contains(i.EventCalendarId)))
                {
                    var eventCalendarItem = eventItem.EventCalendarItems.Where(a => a.Guid == calendar.Guid).FirstOrDefault();
                    if (eventCalendarItem == null)
                    {
                        eventCalendarItem = new EventCalendarItem();
                        eventItem.EventCalendarItems.Add(eventCalendarItem);
                    }
                    eventCalendarItem.CopyPropertiesFrom(calendar);
                }

                if (!eventItem.EventCalendarItems.Any())
                {
                    validationMessages.Add("At least one calendar is required.");
                }

                if (!Page.IsValid)
                {
                    return;
                }

                if (!eventItem.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                if (validationMessages.Any())
                {
                    nbValidation.Text    = "Please Correct the Following<ul><li>" + validationMessages.AsDelimited("</li><li>") + "</li></ul>";
                    nbValidation.Visible = true;
                    return;
                }

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction(() =>
                {
                    rockContext.SaveChanges();
                    foreach (EventCalendarItem eventCalendarItem in eventItem.EventCalendarItems)
                    {
                        eventCalendarItem.LoadAttributes();
                        Rock.Attribute.Helper.GetEditValues(phAttributes, eventCalendarItem);
                        eventCalendarItem.SaveAttributeValues();
                    }

                    if (orphanedImageId.HasValue)
                    {
                        BinaryFileService binaryFileService = new BinaryFileService(rockContext);
                        var binaryFile = binaryFileService.Get(orphanedImageId.Value);
                        if (binaryFile != null)
                        {
                            // marked the old images as IsTemporary so they will get cleaned up later
                            binaryFile.IsTemporary = true;
                            rockContext.SaveChanges();
                        }
                    }
                });


                // Redirect back to same page so that item grid will show any attributes that were selected to show on grid
                var qryParams = new Dictionary <string, string>();
                if (_calendarId.HasValue)
                {
                    qryParams["EventCalendarId"] = _calendarId.Value.ToString();
                }
                qryParams["EventItemId"] = eventItem.Id.ToString();
                NavigateToPage(RockPage.Guid, qryParams);
            }
        }
Example #19
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click( object sender, EventArgs e )
        {
            EventItem eventItem = null;

            using ( var rockContext = new RockContext() )
            {
                var validationMessages = new List<string>();

                var eventItemService = new EventItemService( rockContext );
                var eventCalendarItemService = new EventCalendarItemService( rockContext );
                var eventItemAudienceService = new EventItemAudienceService( rockContext );

                int eventItemId = hfEventItemId.ValueAsInt();
                if ( eventItemId != 0 )
                {
                    eventItem = eventItemService
                        .Queryable( "EventItemAudiences,EventItemOccurrences.Linkages,EventItemOccurrences" )
                        .Where( i => i.Id == eventItemId )
                        .FirstOrDefault();
                }

                if ( eventItem == null )
                {
                    eventItem = new EventItem();
                    eventItemService.Add( eventItem );
                }

                eventItem.Name = tbName.Text;
                eventItem.IsActive = cbIsActive.Checked;

                if ( !eventItem.IsApproved && cbIsApproved.Checked )
                {
                    eventItem.ApprovedByPersonAliasId = CurrentPersonAliasId;
                    eventItem.ApprovedOnDateTime = RockDateTime.Now;
                }
                eventItem.IsApproved = cbIsApproved.Checked;
                if ( !eventItem.IsApproved )
                {
                    eventItem.ApprovedByPersonAliasId = null;
                    eventItem.ApprovedByPersonAlias = null;
                    eventItem.ApprovedOnDateTime = null;
                }
                eventItem.Description = htmlDescription.Text;
                eventItem.Summary = tbSummary.Text;
                eventItem.DetailsUrl = tbDetailUrl.Text;

                int? orphanedImageId = null;
                if ( eventItem.PhotoId != imgupPhoto.BinaryFileId )
                {
                    orphanedImageId = eventItem.PhotoId;
                    eventItem.PhotoId = imgupPhoto.BinaryFileId;
                }

                // Remove any audiences that were removed in the UI
                foreach ( var eventItemAudience in eventItem.EventItemAudiences.Where( r => !AudiencesState.Contains( r.DefinedValueId ) ).ToList() )
                {
                    eventItem.EventItemAudiences.Remove( eventItemAudience );
                    eventItemAudienceService.Delete( eventItemAudience );
                }

                // Add or Update audiences from the UI
                foreach ( int audienceId in AudiencesState )
                {
                    EventItemAudience eventItemAudience = eventItem.EventItemAudiences.Where( a => a.DefinedValueId == audienceId ).FirstOrDefault();
                    if ( eventItemAudience == null )
                    {
                        eventItemAudience = new EventItemAudience();
                        eventItemAudience.DefinedValueId = audienceId;
                        eventItem.EventItemAudiences.Add( eventItemAudience );
                    }
                }

                // remove any calendar items that removed in the UI
                var calendarIds = new List<int>();
                calendarIds.AddRange( cblCalendars.SelectedValuesAsInt );
                var uiCalendarGuids = ItemsState.Where( i => calendarIds.Contains( i.EventCalendarId ) ).Select( a => a.Guid );
                foreach ( var eventCalendarItem in eventItem.EventCalendarItems.Where( a => !uiCalendarGuids.Contains( a.Guid ) ).ToList() )
                {
                    // Make sure user is authorized to remove calendar (they may not have seen every calendar due to security)
                    if ( UserCanEdit || eventCalendarItem.EventCalendar.IsAuthorized( Authorization.EDIT, CurrentPerson ) )
                    {
                        eventItem.EventCalendarItems.Remove( eventCalendarItem );
                        eventCalendarItemService.Delete( eventCalendarItem );
                    }
                }

                // Add or Update calendar items from the UI
                foreach ( var calendar in ItemsState.Where( i => calendarIds.Contains( i.EventCalendarId ) ) )
                {
                    var eventCalendarItem = eventItem.EventCalendarItems.Where( a => a.Guid == calendar.Guid ).FirstOrDefault();
                    if ( eventCalendarItem == null )
                    {
                        eventCalendarItem = new EventCalendarItem();
                        eventItem.EventCalendarItems.Add( eventCalendarItem );
                    }
                    eventCalendarItem.CopyPropertiesFrom( calendar );
                }

                if ( !eventItem.EventCalendarItems.Any() )
                {
                    validationMessages.Add( "At least one calendar is required." );
                }

                if ( !Page.IsValid )
                {
                    return;
                }

                if ( !eventItem.IsValid )
                {
                    // Controls will render the error messages
                    return;
                }

                if ( validationMessages.Any() )
                {
                    nbValidation.Text = "Please Correct the Following<ul><li>" + validationMessages.AsDelimited( "</li><li>" ) + "</li></ul>";
                    nbValidation.Visible = true;
                    return;
                }

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction( () =>
                {
                    rockContext.SaveChanges();
                    foreach ( EventCalendarItem eventCalendarItem in eventItem.EventCalendarItems )
                    {
                        eventCalendarItem.LoadAttributes();
                        Rock.Attribute.Helper.GetEditValues( phAttributes, eventCalendarItem );
                        eventCalendarItem.SaveAttributeValues();
                    }

                    if ( orphanedImageId.HasValue )
                    {
                        BinaryFileService binaryFileService = new BinaryFileService( rockContext );
                        var binaryFile = binaryFileService.Get( orphanedImageId.Value );
                        if ( binaryFile != null )
                        {
                            // marked the old images as IsTemporary so they will get cleaned up later
                            binaryFile.IsTemporary = true;
                            rockContext.SaveChanges();
                        }
                    }
                } );

                // Redirect back to same page so that item grid will show any attributes that were selected to show on grid
                var qryParams = new Dictionary<string, string>();
                if ( _calendarId.HasValue )
                {
                    qryParams["EventCalendarId"] = _calendarId.Value.ToString();
                }
                qryParams["EventItemId"] = eventItem.Id.ToString();
                NavigateToPage( RockPage.Guid, qryParams );
            }
        }