public void ShouldAddToRepositoryAndReturnTrue()
        {
            var ship = new Ship();

            shipRepositoryMock.Setup(x => x.Find(shipId)).Returns(ship);
            var entity = new Schedule();

            var result = service.Add(entity, shipId);

            Assert.IsTrue(result);
            Assert.AreEqual(ship, entity.Ship);
            repositoryMock.Verify(x => x.Add(entity), Times.Once());
            shipRepositoryMock.Verify(x => x.Find(shipId), Times.Once());
        }
Esempio n. 2
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)
        {
            Schedule        schedule;
            ScheduleService scheduleService = new ScheduleService();

            int scheduleId = int.Parse(hfScheduleId.Value);

            if (scheduleId == 0)
            {
                schedule = new Schedule();
                scheduleService.Add(schedule, CurrentPersonId);
            }
            else
            {
                schedule = scheduleService.Get(scheduleId);
            }

            schedule.Name             = tbScheduleName.Text;
            schedule.Description      = tbScheduleDescription.Text;
            schedule.iCalendarContent = sbSchedule.iCalendarContent;

            schedule.CategoryId = cpCategory.SelectedValueAsInt();

            int offsetMins = int.MinValue;

            if (int.TryParse(nbStartOffset.Text, out offsetMins))
            {
                schedule.CheckInStartOffsetMinutes = offsetMins;
            }
            else
            {
                schedule.CheckInStartOffsetMinutes = null;
            }

            offsetMins = int.MinValue;
            if (int.TryParse(nbEndOffset.Text, out offsetMins))
            {
                schedule.CheckInEndOffsetMinutes = offsetMins;
            }
            else
            {
                schedule.CheckInEndOffsetMinutes = null;
            }

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

            RockTransactionScope.WrapTransaction(() =>
            {
                scheduleService.Save(schedule, CurrentPersonId);
            });

            var qryParams = new Dictionary <string, string>();

            qryParams["ScheduleId"] = schedule.Id.ToString();
            NavigateToPage(this.CurrentPage.Guid, qryParams);
        }
Esempio n. 3
0
        /// <summary>
        /// 添加日程
        /// </summary>
        /// <param name="context"></param>
        private void AddSchedule(HttpContext context)
        {
            string result = "";

            string id = context.Request.Form["id"].SafeToString();

            Schedule model     = new Schedule();
            string   Name      = context.Request.Form["Content"].SafeToString();
            DateTime StartDate = Convert.ToDateTime(context.Request.Form["StartDate"].SafeToString());
            DateTime EndDate   = Convert.ToDateTime(context.Request.Form["EndDate"].SafeToString());
            string   AllDay    = context.Request.Form["AllDay"].SafeToString();
            string   EndTime   = context.Request.Form["EndTime"].SafeToString();
            string   IdCard    = context.Request.Form["IdCard"].SafeToString();

            model.Name      = Name;
            model.Content   = Name;
            model.StartDate = StartDate;
            model.EndDate   = EndDate;
            model.CreateUID = IdCard;
            model.AllDay    = Convert.ToInt32(AllDay);
            model.isEndTime = Convert.ToInt32(EndTime);
            if (id != "")
            {
                model.ID  = Convert.ToInt32(id);
                jsonModel = bll.Update(model);
            }
            else
            {
                jsonModel = bll.Add(model);
            }
            result = "{\"result\":" + jss.Serialize(jsonModel) + "}";
            context.Response.Write(result);
        }
Esempio n. 4
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)
        {
            Schedule        schedule;
            var             rockContext     = new RockContext();
            ScheduleService scheduleService = new ScheduleService(rockContext);

            int scheduleId = int.Parse(hfScheduleId.Value);

            if (scheduleId == 0)
            {
                schedule = new Schedule();
                scheduleService.Add(schedule);
            }
            else
            {
                schedule = scheduleService.Get(scheduleId);
            }

            schedule.Name             = tbScheduleName.Text;
            schedule.Description      = tbScheduleDescription.Text;
            schedule.iCalendarContent = sbSchedule.iCalendarContent;

            schedule.CategoryId = cpCategory.SelectedValueAsInt();

            int offsetMins = int.MinValue;

            if (int.TryParse(nbStartOffset.Text, out offsetMins))
            {
                schedule.CheckInStartOffsetMinutes = offsetMins;
            }
            else
            {
                schedule.CheckInStartOffsetMinutes = null;
            }

            offsetMins = int.MinValue;
            if (int.TryParse(nbEndOffset.Text, out offsetMins))
            {
                schedule.CheckInEndOffsetMinutes = offsetMins;
            }
            else
            {
                schedule.CheckInEndOffsetMinutes = null;
            }

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

            rockContext.SaveChanges();

            var qryParams = new Dictionary <string, string>();

            qryParams["ScheduleId"]  = schedule.Id.ToString();
            qryParams["ExpandedIds"] = PageParameter("ExpandedIds");
            NavigateToPage(RockPage.Guid, qryParams);
        }
        public async Task <IHttpActionResult> PostSchedule(ScheduleCreateViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var schedule = await _schedules.Add(new Schedule
            {
                TimeStarted  = model.TimeStarted,
                TimeFinished = model.TimeFinished,
                DayOfWeek    = model.DayOfWeek
            });

            return(CreatedAtRoute("DefaultApi", new { id = schedule.Id }, (ScheduleResultViewModel)schedule));
        }
        protected void btnSave_Click(object sender, EventArgs e)
        {
            var rockContext = new RockContext();
            RecurringCommunicationService recurringCommunicationService = new RecurringCommunicationService(rockContext);
            var recurringCommunication = GetRecurringCommunication(recurringCommunicationService);

            if (recurringCommunication.Schedule == null)
            {
                recurringCommunication.Schedule = new Schedule();
                ScheduleService scheduleService = new ScheduleService(rockContext);
                scheduleService.Add(recurringCommunication.Schedule);
            }
            recurringCommunication.Name       = tbName.Text;
            recurringCommunication.DataViewId = dvpDataview.SelectedValue.AsInteger();
            recurringCommunication.Schedule.iCalendarContent = sbScheduleBuilder.iCalendarContent;
            recurringCommunication.CommunicationType         = rblCommunicationType.SelectedValueAsEnum <CommunicationType>();
            recurringCommunication.FromName                   = tbFromName.Text;
            recurringCommunication.FromEmail                  = tbFromEmail.Text;
            recurringCommunication.Subject                    = tbSubject.Text;
            recurringCommunication.EmailBody                  = ceEmailBody.Text;
            recurringCommunication.PhoneNumberValueId         = dvpPhoneNumber.SelectedDefinedValueId > 0 ? dvpPhoneNumber.SelectedDefinedValueId : null;
            recurringCommunication.SMSBody                    = tbSMSBody.Text;
            recurringCommunication.PushTitle                  = tbPushNotificationTitle.Text;
            recurringCommunication.PushMessage                = tbPushNotificationBody.Text;
            recurringCommunication.PushSound                  = cbPlaySound.Checked ? "default" : string.Empty;
            recurringCommunication.TransformationEntityTypeId = ddlTransformTypes.SelectedValue.AsIntegerOrNull();


            if (recurringCommunication.Id == 0)
            {
                recurringCommunicationService.Add(recurringCommunication);
            }
            recurringCommunication.ScheduleDescription = GetScheduleDescription();
            rockContext.SaveChanges();
            NavigateToParentPage();
        }
Esempio n. 7
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)
        {
            Metric metric;

            var                   rockContext           = new RockContext();
            MetricService         metricService         = new MetricService(rockContext);
            MetricCategoryService metricCategoryService = new MetricCategoryService(rockContext);
            MetricValueService    metricValueService    = new MetricValueService(rockContext);
            bool                  deleteValuesOnSave    = sender == btnDeleteValuesAndSave;

            int metricId = hfMetricId.Value.AsInteger();

            if (metricId == 0)
            {
                metric = new Metric();
            }
            else
            {
                metric = metricService.Get(metricId);
            }

            metric.Title             = tbTitle.Text;
            metric.Subtitle          = tbSubtitle.Text;
            metric.Description       = tbDescription.Text;
            metric.IconCssClass      = tbIconCssClass.Text;
            metric.SourceValueTypeId = ddlSourceType.SelectedValueAsId();
            metric.XAxisLabel        = tbXAxisLabel.Text;
            metric.YAxisLabel        = tbYAxisLabel.Text;
            metric.IsCumulative      = cbIsCumulative.Checked;

            var origEntityType = metric.EntityTypeId.HasValue ? EntityTypeCache.Read(metric.EntityTypeId.Value) : null;
            var newEntityType  = etpEntityType.SelectedEntityTypeId.HasValue ? EntityTypeCache.Read(etpEntityType.SelectedEntityTypeId.Value) : null;

            if (origEntityType != null && !deleteValuesOnSave)
            {
                if (newEntityType == null || newEntityType.Id != origEntityType.Id)
                {
                    // if the EntityTypeId of this metric has changed to NULL or to another EntityType, warn about the EntityId values being wrong
                    bool hasEntityValues = metricValueService.Queryable().Any(a => a.MetricId == metric.Id && a.EntityId.HasValue);

                    if (hasEntityValues)
                    {
                        nbEntityTypeChanged.Text = string.Format(
                            "Warning: You can't change the series partition to {0} when there are values associated with {1}. Do you want to delete existing values?",
                            newEntityType != null ? newEntityType.FriendlyName : "<none>",
                            origEntityType.FriendlyName);
                        mdEntityTypeChanged.Show();
                        nbEntityTypeChanged.Visible = true;
                        return;
                    }
                }
            }

            metric.EntityTypeId = etpEntityType.SelectedEntityTypeId;

            int sourceTypeDataView = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_DATAVIEW.AsGuid()).Id;
            int sourceTypeSQL      = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_SQL.AsGuid()).Id;

            var personService        = new PersonService(rockContext);
            var metricChampionPerson = personService.Get(ppMetricChampionPerson.SelectedValue ?? 0);

            metric.MetricChampionPersonAliasId = metricChampionPerson != null ? metricChampionPerson.PrimaryAliasId : null;
            var adminPerson = personService.Get(ppAdminPerson.SelectedValue ?? 0);

            metric.AdminPersonAliasId = adminPerson != null ? adminPerson.PrimaryAliasId : null;

            if (metric.SourceValueTypeId == sourceTypeSQL)
            {
                metric.SourceSql = ceSourceSql.Text;
            }
            else
            {
                metric.SourceSql = string.Empty;
            }

            if (metric.SourceValueTypeId == sourceTypeDataView)
            {
                metric.DataViewId = ddlDataView.SelectedValueAsId();
            }
            else
            {
                metric.DataViewId = null;
            }

            var scheduleSelectionType = rblScheduleSelect.SelectedValueAsEnum <ScheduleSelectionType>();

            if (scheduleSelectionType == ScheduleSelectionType.NamedSchedule)
            {
                metric.ScheduleId = ddlSchedule.SelectedValueAsId();
            }
            else
            {
                metric.ScheduleId = hfUniqueScheduleId.ValueAsInt();
            }

            if (!Page.IsValid)
            {
                return;
            }

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

            if (!cpMetricCategories.SelectedValuesAsInt().Any())
            {
                cpMetricCategories.ShowErrorMessage("Must select at least one category");
                return;
            }

            // do a WrapTransaction since we are doing multiple SaveChanges()
            rockContext.WrapTransaction(() =>
            {
                var scheduleService          = new ScheduleService(rockContext);
                var schedule                 = scheduleService.Get(metric.ScheduleId ?? 0);
                int metricScheduleCategoryId = new CategoryService(rockContext).Get(Rock.SystemGuid.Category.SCHEDULE_METRICS.AsGuid()).Id;
                if (schedule == null)
                {
                    schedule = new Schedule();

                    // make it an "Unnamed" metrics schedule
                    schedule.Name       = string.Empty;
                    schedule.CategoryId = metricScheduleCategoryId;
                }

                // if the schedule was a unique schedule (configured in the Metric UI, set the schedule's ical content to the schedule builder UI's value
                if (scheduleSelectionType == ScheduleSelectionType.Unique)
                {
                    schedule.iCalendarContent = sbSchedule.iCalendarContent;
                }

                if (!schedule.HasSchedule() && scheduleSelectionType == ScheduleSelectionType.Unique)
                {
                    // don't save as a unique schedule if the schedule doesn't do anything
                    schedule = null;
                }
                else
                {
                    if (schedule.Id == 0)
                    {
                        scheduleService.Add(schedule);

                        // save to make sure we have a scheduleId
                        rockContext.SaveChanges();
                    }
                }

                if (schedule != null)
                {
                    metric.ScheduleId = schedule.Id;
                }
                else
                {
                    metric.ScheduleId = null;
                }

                if (metric.Id == 0)
                {
                    metricService.Add(metric);

                    // save to make sure we have a metricId
                    rockContext.SaveChanges();
                }

                // update MetricCategories for Metric
                metric.MetricCategories = metric.MetricCategories ?? new List <MetricCategory>();
                var selectedCategoryIds = cpMetricCategories.SelectedValuesAsInt();

                // delete any categories that were removed
                foreach (var metricCategory in metric.MetricCategories.ToList())
                {
                    if (!selectedCategoryIds.Contains(metricCategory.CategoryId))
                    {
                        metricCategoryService.Delete(metricCategory);
                    }
                }

                // add any categories that were added
                foreach (int categoryId in selectedCategoryIds)
                {
                    if (!metric.MetricCategories.Any(a => a.CategoryId == categoryId))
                    {
                        metricCategoryService.Add(new MetricCategory {
                            CategoryId = categoryId, MetricId = metric.Id
                        });
                    }
                }

                rockContext.SaveChanges();

                // delete MetricValues associated with the old entityType if they confirmed the EntityType change
                if (deleteValuesOnSave)
                {
                    metricValueService.DeleteRange(metricValueService.Queryable().Where(a => a.MetricId == metric.Id && a.EntityId.HasValue));

                    // since there could be 1000s of values that got deleted, do a SaveChanges that skips PrePostProcessing
                    rockContext.SaveChanges(true);
                }

                // delete any orphaned Unnamed metric schedules
                var metricIdSchedulesQry = metricService.Queryable().Select(a => a.ScheduleId);
                int?metricScheduleId     = schedule != null ? schedule.Id : (int?)null;
                var orphanedSchedules    = scheduleService.Queryable()
                                           .Where(a => a.CategoryId == metricScheduleCategoryId && a.Name == string.Empty && a.Id != (metricScheduleId ?? 0))
                                           .Where(s => !metricIdSchedulesQry.Any(m => m == s.Id));
                foreach (var item in orphanedSchedules)
                {
                    scheduleService.Delete(item);
                }

                if (orphanedSchedules.Any())
                {
                    rockContext.SaveChanges();
                }
            });

            var qryParams = new Dictionary <string, string>();

            qryParams["MetricId"] = metric.Id.ToString();
            if (hfMetricCategoryId.ValueAsInt() == 0)
            {
                int?parentCategoryId = PageParameter("ParentCategoryId").AsIntegerOrNull();
                int?metricCategoryId = new MetricCategoryService(new RockContext()).Queryable().Where(a => a.MetricId == metric.Id && a.CategoryId == parentCategoryId).Select(a => a.Id).FirstOrDefault();
                hfMetricCategoryId.Value = metricCategoryId.ToString();
            }

            qryParams["MetricCategoryId"] = hfMetricCategoryId.Value;
            qryParams["ExpandedIds"]      = PageParameter("ExpandedIds");

            NavigateToPage(RockPage.Guid, qryParams);
        }
        public void RockCleanup_Execute_ShouldUpdateEventItemOccurrences()
        {
            var referenceDate = new DateTime(2020, 1, 1);

            // Get the sample data schedule for Saturday 4:30pm.
            var rockContext = new RockContext();

            var scheduleService = new ScheduleService(rockContext);
            var schedule        = scheduleService.Get(TestGuids.Schedules.ScheduleSat1630Guid.AsGuid());

            // Create a new inactive schedule.
            var scheduleInactive = scheduleService.Get(testScheduleGuid);

            if (scheduleInactive == null)
            {
                scheduleInactive = new Schedule();
                scheduleService.Add(scheduleInactive);
            }
            scheduleInactive.Name     = "Test Schedule";
            scheduleInactive.Guid     = testScheduleGuid;
            scheduleInactive.IsActive = false;

            rockContext.SaveChanges();

            // Create the Test Events.
            var eventItemService = new EventItemService(rockContext);

            // Test Event 1 (active)
            var testEvent1 = eventItemService.Get(testEvent1Guid);

            if (testEvent1 != null)
            {
                eventItemService.Delete(testEvent1);
                rockContext.SaveChanges();
            }

            testEvent1      = new EventItem();
            testEvent1.Guid = testEvent1Guid;
            testEvent1.Name = "Test Event 1";
            eventItemService.Add(testEvent1);

            // Add an occurrence with a future schedule and no NextDateTime value.
            // When the cleanup task executes, this should be updated to the next occurrence after the reference date.
            var testOccurrence11 = new EventItemOccurrence();

            testOccurrence11.ScheduleId        = schedule.Id;
            testOccurrence11.Guid              = testEventOccurrence11Guid;
            testOccurrence11.NextStartDateTime = null;
            testEvent1.EventItemOccurrences.Add(testOccurrence11);

            // Add an occurrence with a NextDateTime that is prior to the reference date.
            // When the cleanup task executes, this should be updated to the next occurrence after the reference date.
            var testOccurrence12 = new EventItemOccurrence();

            testOccurrence12.ScheduleId        = schedule.Id;
            testOccurrence12.Guid              = testEventOccurrence12Guid;
            testOccurrence12.NextStartDateTime = referenceDate.AddDays(-1);
            testEvent1.EventItemOccurrences.Add(testOccurrence12);

            // Add an occurrence with a NextDateTime and an inactive Schedule.
            // When the cleanup task executes, the NextDateTime should be set to null.
            var testOccurrence13 = new EventItemOccurrence();

            testOccurrence13.ScheduleId        = scheduleInactive.Id;
            testOccurrence13.Guid              = testEventOccurrence13Guid;
            testOccurrence13.NextStartDateTime = referenceDate.AddDays(7);
            testEvent1.EventItemOccurrences.Add(testOccurrence13);

            // Test Event 2 (inactive)
            var testEvent2 = eventItemService.Get(testEvent2Guid);

            if (testEvent2 != null)
            {
                eventItemService.Delete(testEvent2);
                rockContext.SaveChanges();
            }

            testEvent2          = new EventItem();
            testEvent2.Guid     = testEvent2Guid;
            testEvent2.Name     = "Test Event 2";
            testEvent2.IsActive = false;
            eventItemService.Add(testEvent2);

            // Add an occurrence with a future schedule and a NextDateTime value.
            // When the cleanup task executes, the NextDateTime should be set to null.
            var testOccurrence21 = new EventItemOccurrence();

            testOccurrence21.ScheduleId        = schedule.Id;
            testOccurrence21.Guid              = testEventOccurrence21Guid;
            testOccurrence21.NextStartDateTime = referenceDate;
            testEvent2.EventItemOccurrences.Add(testOccurrence21);

            // Save changes without triggering the pre-save, to avoid updating the NextEventDate field.
            rockContext.SaveChanges(new SaveChangesArgs {
                DisablePrePostProcessing = true
            });

            // Run the cleanup task to verify the results for the reference date.
            RunRockCleanupTaskUpdateEventNextOccurrenceDatesAndVerify(referenceDate);

            // Re-run the task to verify that the results are adjusted for the current date.
            RunRockCleanupTaskUpdateEventNextOccurrenceDatesAndVerify(RockDateTime.Now);
        }
Esempio n. 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)
        {
            Metric metric;

            var                   rockContext           = new RockContext();
            MetricService         metricService         = new MetricService(rockContext);
            MetricCategoryService metricCategoryService = new MetricCategoryService(rockContext);

            int metricId = hfMetricId.Value.AsInteger(false) ?? 0;

            if (metricId == 0)
            {
                metric = new Metric();
            }
            else
            {
                metric = metricService.Get(metricId);
            }

            metric.Title             = tbTitle.Text;
            metric.Subtitle          = tbSubtitle.Text;
            metric.Description       = tbDescription.Text;
            metric.IconCssClass      = tbIconCssClass.Text;
            metric.SourceValueTypeId = ddlSourceType.SelectedValueAsId();
            metric.XAxisLabel        = tbXAxisLabel.Text;
            metric.YAxisLabel        = tbYAxisLabel.Text;
            metric.IsCumulative      = cbIsCumulative.Checked;
            metric.EntityTypeId      = etpEntityType.SelectedEntityTypeId;

            var personService        = new PersonService(rockContext);
            var metricChampionPerson = personService.Get(ppMetricChampionPerson.SelectedValue ?? 0);

            metric.MetricChampionPersonAliasId = metricChampionPerson != null ? metricChampionPerson.PrimaryAliasId : null;
            var adminPerson = personService.Get(ppAdminPerson.SelectedValue ?? 0);

            metric.AdminPersonAliasId = adminPerson != null ? adminPerson.PrimaryAliasId : null;
            metric.SourceSql          = ceSourceSql.Text;
            metric.DataViewId         = ddlDataView.SelectedValueAsId();

            if (rblScheduleSelect.SelectedValueAsEnum <ScheduleSelectionType>() == ScheduleSelectionType.NamedSchedule)
            {
                metric.ScheduleId = ddlSchedule.SelectedValueAsId();
            }
            else
            {
                metric.ScheduleId = hfUniqueScheduleId.ValueAsInt();
            }

            if (!Page.IsValid)
            {
                return;
            }

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

            if (!cpMetricCategories.SelectedValuesAsInt().Any())
            {
                cpMetricCategories.ShowErrorMessage("Must select at least one category");
                return;
            }

            // do a WrapTransaction since we are doing multiple SaveChanges()
            RockTransactionScope.WrapTransaction(() =>
            {
                var scheduleService          = new ScheduleService(rockContext);
                var schedule                 = scheduleService.Get(metric.ScheduleId ?? 0);
                int metricScheduleCategoryId = new CategoryService(rockContext).Get(Rock.SystemGuid.Category.SCHEDULE_METRICS.AsGuid()).Id;
                if (schedule == null)
                {
                    schedule = new Schedule();

                    // make it an "Unnamed" metrics schedule
                    schedule.Name       = string.Empty;
                    schedule.CategoryId = metricScheduleCategoryId;
                }

                schedule.iCalendarContent = sbSchedule.iCalendarContent;
                if (schedule.Id == 0)
                {
                    scheduleService.Add(schedule);

                    // save to make sure we have a scheduleId
                    rockContext.SaveChanges();
                }

                metric.ScheduleId = schedule.Id;

                if (metric.Id == 0)
                {
                    metricService.Add(metric);

                    // save to make sure we have a metricId
                    rockContext.SaveChanges();
                }

                // update MetricCategories for Metric
                metric.MetricCategories = metric.MetricCategories ?? new List <MetricCategory>();
                var selectedCategoryIds = cpMetricCategories.SelectedValuesAsInt();

                // delete any categories that were removed
                foreach (var metricCategory in metric.MetricCategories)
                {
                    if (!selectedCategoryIds.Contains(metricCategory.CategoryId))
                    {
                        metricCategoryService.Delete(metricCategory);
                    }
                }

                // add any categories that were added
                foreach (int categoryId in selectedCategoryIds)
                {
                    if (!metric.MetricCategories.Any(a => a.CategoryId == categoryId))
                    {
                        metricCategoryService.Add(new MetricCategory {
                            CategoryId = categoryId, MetricId = metric.Id
                        });
                    }
                }

                rockContext.SaveChanges();

                // delete any orphaned Unnamed metric schedules
                var metricIdSchedulesQry = metricService.Queryable().Select(a => a.ScheduleId);
                var orphanedSchedules    = scheduleService.Queryable()
                                           .Where(a => a.CategoryId == metricScheduleCategoryId && a.Name == string.Empty && a.Id != schedule.Id)
                                           .Where(s => !metricIdSchedulesQry.Any(m => m == s.Id));
                foreach (var item in orphanedSchedules)
                {
                    scheduleService.Delete(item);
                }

                if (orphanedSchedules.Any())
                {
                    rockContext.SaveChanges();
                }
            });

            var qryParams = new Dictionary <string, string>();

            qryParams["MetricId"] = metric.Id.ToString();
            if (hfMetricCategoryId.ValueAsInt() == 0)
            {
                int?parentCategoryId = PageParameter("ParentCategoryId").AsInteger();
                int?metricCategoryId = new MetricCategoryService(new RockContext()).Queryable().Where(a => a.MetricId == metric.Id && a.CategoryId == parentCategoryId).Select(a => a.Id).FirstOrDefault();
                hfMetricCategoryId.Value = metricCategoryId.ToString();
            }

            qryParams["MetricCategoryId"] = hfMetricCategoryId.Value;

            NavigateToPage(RockPage.Guid, qryParams);
        }
Esempio n. 10
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Check Api connection first.
            if (!Zoom.ZoomAuthCheck())
            {
                context.Result = "Zoom API authentication error. Check API settings for Zoom Room plugin or try again later.";
                throw new Exception("Authentication failed for Zoom API. Please verify the API settings configured in the Zoom Room plugin are valid and correct.");
            }

            using (var rockContext = new RockContext())
            {
                #region Setup Variables

                int      jobId                  = context.JobDetail.Description.AsInteger();
                var      job                    = new ServiceJobService(rockContext).GetNoTracking(jobId);
                var      JobStartDateTime       = RockDateTime.Now;
                DateTime?lastSuccessRunDateTime = null;
                if (job != null && job.Guid != Rock.SystemGuid.ServiceJob.JOB_PULSE.AsGuid())
                {
                    lastSuccessRunDateTime = job.LastSuccessfulRunDateTime;
                }

                // get the last run date or yesterday
                var beginDateTime = lastSuccessRunDateTime ?? JobStartDateTime.AddDays(-1);

                var dataMap = context.JobDetail.JobDataMap;
                var daysOut = dataMap.GetIntegerFromString(AttributeKey.SyncDaysOut);
                webhookBaseUrl = Settings.GetWebhookUrl();
                var importMeetings = dataMap.GetBooleanFromString(AttributeKey.ImportMeetings);
                verboseLogging = dataMap.GetBooleanFromString(AttributeKey.VerboseLogging);
                var zrOccurrencesCancel = new List <RoomOccurrence>();
                reservationLocationEntityTypeId = new EntityTypeService(rockContext).GetNoTracking(com.bemaservices.RoomManagement.SystemGuid.EntityType.RESERVATION_LOCATION.AsGuid()).Id;

                var zoom            = Zoom.Api();
                var locationService = new LocationService(rockContext);
                var zrLocations     = locationService.Queryable()
                                      .AsNoTracking()
                                      .WhereAttributeValue(rockContext, a => a.Attribute.Key == "rocks.kfs.ZoomRoom" && a.Value != null && a.Value != "")
                                      .ToList();
                var zrLocationIds           = zrLocations.Select(l => l.Id).ToList();
                var linkedZoomRoomLocations = new Dictionary <int, string>();
                foreach (var loc in zrLocations)
                {
                    loc.LoadAttributes();
                    var zoomRoomDV = DefinedValueCache.Get(loc.GetAttributeValue("rocks.kfs.ZoomRoom").AsGuid());
                    linkedZoomRoomLocations.Add(loc.Id, zoomRoomDV.Value);
                }

                #endregion Setup Variables

                #region Mark Completed Occurrences

                var zrOccurrenceService  = new RoomOccurrenceService(rockContext);
                var completedOccurrences = zrOccurrenceService.Queryable()
                                           .Where(ro => ro.IsCompleted == false &&
                                                  DbFunctions.AddMinutes(ro.StartTime, ro.Duration) < beginDateTime);
                foreach (var occ in completedOccurrences)
                {
                    occ.IsCompleted = true;
                }
                rockContext.SaveChanges();

                #endregion Mark Completed Occurrences

                #region Cleanup

                var reservationLocationService = new ReservationLocationService(rockContext);
                var reservationLocationIds     = reservationLocationService.Queryable().AsNoTracking().Select(rl => rl.Id);

                // Delete any orphaned RoomOccurrences ( tied to invalid/deleted ReservationId )
                zrOccurrenceService = new RoomOccurrenceService(rockContext);
                var orphanedOccs = zrOccurrenceService.Queryable()
                                   .Where(ro => ro.EntityTypeId == reservationLocationEntityTypeId &&
                                          !reservationLocationIds.Any(id => id == ro.EntityId));
                if (orphanedOccs.Count() > 0)
                {
                    if (verboseLogging)
                    {
                        LogEvent(rockContext, "Zoom Room Reservation Sync", string.Format("Preparing to delete {0} orphaned RoomOccurrence(s)."));
                    }
                    zrOccurrenceService.DeleteRange(orphanedOccs);
                    var errors = new List <string>();
                    LogEvent(null, "Zoom Room Reservation Sync", string.Format("{0} orphaned RoomOccurrence(s) deleted.", orphanedOccs.Count()));
                    if (verboseLogging)
                    {
                        LogEvent(null, "Zoom Room Reservation Sync", "Deleting related Zoom Meetings.");
                    }
                    DeleteOccurrenceZoomMeetings(orphanedOccs, zoom);
                    rockContext.SaveChanges();
                }

                // Delete any active Room Occurrences tied to Zoom Meetings that no longer exist.
                var linkedOccurrences = zrOccurrenceService
                                        .Queryable()
                                        .AsNoTracking()
                                        .Where(ro => ro.EntityTypeId == reservationLocationEntityTypeId &&
                                               ro.ZoomMeetingId > 0 &&
                                               !ro.IsCompleted &&
                                               ro.StartTime >= beginDateTime);
                var zoomMeetings = new List <Meeting>();
                foreach (var zrl in linkedZoomRoomLocations)
                {
                    zoomMeetings.AddRange(zoom.GetZoomMeetings(zrl.Value, MeetingListType.Upcoming));
                }
                var zoomMeetingIds      = zoomMeetings.Select(m => m.Id).ToList();
                var orphanedOccurrences = linkedOccurrences.Where(ro => !zoomMeetingIds.Any(mid => mid == ro.ZoomMeetingId));
                if (orphanedOccurrences.Count() > 0)
                {
                    zrOccurrenceService.DeleteRange(orphanedOccurrences);
                    rockContext.SaveChanges();
                }

                // Attempt to create Zoom Room Meeting for any Room Occurrences that may have had previous issues.
                var unlinkedOccurrences = zrOccurrenceService
                                          .Queryable()
                                          .Where(ro => ro.EntityTypeId == reservationLocationEntityTypeId &&
                                                 (!ro.ZoomMeetingId.HasValue || ro.ZoomMeetingId <= 0) &&
                                                 !ro.IsCompleted &&
                                                 ro.StartTime >= beginDateTime &&
                                                 (ro.ZoomMeetingRequestStatus == ZoomMeetingRequestStatus.Failed || ro.ZoomMeetingRequestStatus == ZoomMeetingRequestStatus.ZoomRoomOffline));

                foreach (var rOcc in unlinkedOccurrences)
                {
                    var rLoc = reservationLocationService.Queryable("Location").FirstOrDefault(rl => rl.Id == rOcc.EntityId);
                    rLoc.Location.LoadAttributes();
                    rOcc.ZoomMeetingRequestStatus = ZoomMeetingRequestStatus.Requested;
                    var zoomRoomDV = DefinedValueCache.Get(rLoc.Location.GetAttributeValue("rocks.kfs.ZoomRoom").AsGuid());
                    CreateOccurrenceZoomMeeting(rOcc, zoomRoomDV, zoom);
                }
                if (unlinkedOccurrences.Count() > 0)
                {
                    rockContext.SaveChanges();
                }

                #endregion Cleanup

                #region External Zoom Meetings

                var scheduleService           = new ScheduleService(rockContext);
                var reservationService        = new ReservationService(rockContext);
                var reservationTypeService    = new ReservationTypeService(rockContext);
                var zoomImportReservationType = reservationTypeService.Get(RoomReservationType.ZOOMROOMIMPORT.AsGuid());

                // Create RoomOccurrences for any Zoom Room meetings created outside of Rock
                if (importMeetings && linkedZoomRoomLocations.Count > 0)
                {
                    var linkedMeetings   = linkedOccurrences.Select(ro => ro.ZoomMeetingId).ToList();
                    var zoomRoomMeetings = zoomMeetings.Where(m => m.Start_Time > beginDateTime);
                    var missingMeetings  = zoomRoomMeetings.Where(m => !linkedMeetings.Any(mid => mid == m.Id));
                    if (missingMeetings.Count() > 0)
                    {
                        foreach (var zrl in linkedZoomRoomLocations)
                        {
                            foreach (var meeting in missingMeetings.Where(m => m.Host_Id == zrl.Value))
                            {
                                // Build the iCal string as it is a required property on the Schedule for Room Reservation block to display the Reservation
                                var meetingLocalTime = meeting.Start_Time.UtcDateTime.ToLocalTime();
                                var calendarEvent    = new Event
                                {
                                    DtStart = new CalDateTime(meetingLocalTime),
                                    DtEnd   = new CalDateTime(meetingLocalTime.AddMinutes(meeting.Duration)),
                                    DtStamp = new CalDateTime(meetingLocalTime.Year, meetingLocalTime.Month, meetingLocalTime.Day)
                                };
                                var calendar = new Calendar();
                                calendar.Events.Add(calendarEvent);
                                var serializer = new CalendarSerializer(calendar);

                                var schedule = new Schedule
                                {
                                    Guid = Guid.NewGuid(),
                                    EffectiveStartDate = meetingLocalTime,
                                    EffectiveEndDate   = meetingLocalTime.AddMinutes(meeting.Duration),
                                    IsActive           = true,
                                    iCalendarContent   = serializer.SerializeToString()
                                };
                                scheduleService.Add(schedule);

                                var location       = locationService.Get(zrl.Key);
                                var newReservation = new Reservation
                                {
                                    Name = location.Name.Left(50),    // NOTE: Reservation.Name is limited to 50 chars but Location.Name is up to 100 chars.
                                    ReservationTypeId = zoomImportReservationType.Id,
                                    Guid            = Guid.NewGuid(),
                                    Schedule        = schedule,
                                    NumberAttending = 0,
                                    Note            = string.Format("Created from import of \"{0}\" meeting ({1}) from Zoom Room \"{2}\".", meeting.Topic, meeting.Id, zrl.Value),
                                    ApprovalState   = ReservationApprovalState.Approved
                                };
                                reservationService.Add(newReservation);

                                var reservationLocation = new ReservationLocation
                                {
                                    Reservation   = newReservation,
                                    Location      = location,
                                    ApprovalState = ReservationLocationApprovalState.Approved
                                };
                                reservationLocationService.Add(reservationLocation);
                                rockContext.SaveChanges();

                                var occurrence = new RoomOccurrence
                                {
                                    ZoomMeetingId = meeting.Id,
                                    EntityTypeId  = reservationLocationEntityTypeId,
                                    EntityId      = reservationLocation.Id,
                                    Schedule      = schedule,
                                    LocationId    = reservationLocation.LocationId,
                                    Topic         = meeting.Topic,
                                    StartTime     = meetingLocalTime,
                                    Password      = meeting.Password,
                                    Duration      = meeting.Duration,
                                    TimeZone      = meeting.Timezone
                                };
                                zrOccurrenceService.Add(occurrence);
                                rockContext.SaveChanges();
                            }
                        }
                    }
                }

                #endregion External Zoom Meetings

                #region Process Reservations

                var reservations = reservationService.Queryable("Schedule,ReservationLocations,ReservationType")
                                   .AsNoTracking()
                                   .Where(r => r.ModifiedDateTime >= beginDateTime &&
                                          r.ReservationTypeId != zoomImportReservationType.Id &&
                                          (r.ApprovalState == ReservationApprovalState.Approved ||
                                           (!r.ReservationType.IsReservationBookedOnApproval && r.ApprovalState != ReservationApprovalState.Cancelled && r.ApprovalState != ReservationApprovalState.Denied && r.ApprovalState != ReservationApprovalState.Draft)) &&
                                          r.ReservationLocations.Any(rl => zrLocationIds.Contains(rl.LocationId)) &&
                                          r.Schedule != null &&
                                          ((r.Schedule.EffectiveEndDate != null && r.Schedule.EffectiveEndDate > DbFunctions.AddDays(RockDateTime.Today, -1)) ||
                                           (r.Schedule.EffectiveEndDate == null && r.Schedule.EffectiveStartDate != null && r.Schedule.EffectiveStartDate > DbFunctions.AddDays(RockDateTime.Today, -1))))
                                   .ToList();
                var resLocationIdsToProcess = new List <int>();
                var zrOccurrencesAdded      = 0;
                if (verboseLogging)
                {
                    LogEvent(rockContext, "Zoom Room Reservation Sync", string.Format("{0} Room Reservation(s) to be processed", reservations.Count()));
                }
                foreach (var res in reservations)
                {
                    foreach (var rl in res.ReservationLocations.Where(rl => zrLocationIds.Contains(rl.LocationId)).ToList())
                    {
                        rl.Location.LoadAttributes();
                        var zoomRoomDV = DefinedValueCache.Get(rl.Location.AttributeValues.FirstOrDefault(v => v.Key == "rocks.kfs.ZoomRoom").Value.Value.AsGuid());
                        var zrPassword = zoomRoomDV.GetAttributeValue("rocks.kfs.ZoomMeetingPassword");
                        resLocationIdsToProcess.Add(rl.Id);
                        var resLocOccurrences = zrOccurrenceService.Queryable().Where(ro => ro.EntityTypeId == reservationLocationEntityTypeId && ro.EntityId == rl.Id);

                        // One-Time Schedule
                        if (res.Schedule.EffectiveEndDate is null || res.Schedule.EffectiveStartDate.Value == res.Schedule.EffectiveEndDate.Value)
                        {
                            var occurrence = new RoomOccurrence();
                            if (resLocOccurrences.Count() == 0)
                            {
                                occurrence = new RoomOccurrence
                                {
                                    Id                       = 0,
                                    EntityTypeId             = reservationLocationEntityTypeId,
                                    EntityId                 = rl.Id,
                                    ScheduleId               = res.ScheduleId,
                                    LocationId               = rl.LocationId,
                                    Topic                    = res.Name,
                                    StartTime                = res.Schedule.FirstStartDateTime.Value,
                                    Password                 = zrPassword,
                                    Duration                 = res.Schedule.DurationInMinutes,
                                    IsCompleted              = false,
                                    ZoomMeetingRequestStatus = ZoomMeetingRequestStatus.Requested
                                };
                                zrOccurrenceService.Add(occurrence);
                                rockContext.SaveChanges();
                                zrOccurrencesAdded++;

                                if (CreateOccurrenceZoomMeeting(occurrence, zoomRoomDV, zoom))
                                {
                                    rockContext.SaveChanges();
                                }
                            }
                            else
                            {
                                Meeting connectedMeeting = null;
                                var     updateMeeting    = false;
                                occurrence = resLocOccurrences.FirstOrDefault();
                                if (occurrence.ZoomMeetingId.HasValue && occurrence.ZoomMeetingId.Value > 0)
                                {
                                    connectedMeeting = zoomMeetings.FirstOrDefault(m => m.Id == occurrence.ZoomMeetingId.Value);
                                    if (connectedMeeting == null)
                                    {
                                        occurrence.ZoomMeetingId = null;
                                    }
                                }
                                if (occurrence.IsCompleted)
                                {
                                    occurrence.IsCompleted = false;
                                }
                                if (occurrence.ScheduleId != res.ScheduleId)
                                {
                                    occurrence.ScheduleId = res.ScheduleId;
                                }
                                if (occurrence.StartTime != res.Schedule.FirstStartDateTime.Value)
                                {
                                    occurrence.StartTime = res.Schedule.FirstStartDateTime.Value;
                                }
                                if (connectedMeeting != null && connectedMeeting.Start_Time != occurrence.StartTime.ToRockDateTimeOffset())
                                {
                                    connectedMeeting.Start_Time = occurrence.StartTime.ToRockDateTimeOffset();
                                    updateMeeting = true;
                                }
                                if (occurrence.Duration != res.Schedule.DurationInMinutes)
                                {
                                    occurrence.Duration = res.Schedule.DurationInMinutes;
                                    if (connectedMeeting != null)
                                    {
                                        connectedMeeting.Duration = res.Schedule.DurationInMinutes;
                                        updateMeeting             = true;
                                    }
                                }
                                if (occurrence.Topic != res.Name)
                                {
                                    occurrence.Topic = res.Name;
                                    if (connectedMeeting != null)
                                    {
                                        connectedMeeting.Topic = res.Name;
                                        updateMeeting          = true;
                                    }
                                }
                                if (updateMeeting)
                                {
                                    zoom.UpdateMeeting(connectedMeeting);
                                }
                            }
                        }