/// <summary> /// Create a <see cref="ChangelogSection"/> that states that the <see cref="EngineeringModel"/> wasn't found in the database (anymore) /// </summary> /// <param name="changeNotificationSubscriptionUserPreference"> /// The <see cref="ChangeNotificationSubscriptionUserPreference"/> /// </param> /// <returns> /// The created <see cref="ChangelogSection"/> /// </returns> private ChangelogSection CreateEngineeringModelNotFoundSection(ChangeNotificationSubscriptionUserPreference changeNotificationSubscriptionUserPreference) { return (new ChangelogSection( $"{changeNotificationSubscriptionUserPreference.Name}", "Failed", "EngineeringModel not found")); }
/// <summary> /// Create an <see cref="IEnumerable{T}"/> of type <see cref="ModelLogEntryData"/> for a specific <see cref="EngineeringModel"/> /// base on a list of filtered <see cref="ModelLogEntry"/>s /// </summary> /// <param name="transaction"> /// The current <see cref="NpgsqlTransaction"/> to the database. /// </param> /// <param name="engineeringModelPartition"> /// The partition in the database /// </param> /// <param name="container"> /// The <see cref="IContainer"/> used to resolve injectable objects /// </param> /// <param name="modelLogEntries"> /// The <see cref="ModelLogEntry"/>s /// </param> /// <param name="domains"> /// The <see cref="DomainOfExpertise.Iid"/>s used to filter <see cref="LogEntryChangelogItem"/>s to be used. /// </param> /// <param name="changeNotificationSubscriptionUserPreference"> /// The <see cref="ChangeNotificationSubscriptionUserPreference"/> that contains the change notification subscriptions /// </param> /// <returns> /// The created <see cref="IEnumerable{T}"/> of type <see cref="ModelLogEntryData"/> /// </returns> public IEnumerable <ModelLogEntryData> Create( NpgsqlTransaction transaction, string engineeringModelPartition, IContainer container, IEnumerable <ModelLogEntry> modelLogEntries, IEnumerable <Guid> domains, ChangeNotificationSubscriptionUserPreference changeNotificationSubscriptionUserPreference) { var modelLogEntryDataList = new List <ModelLogEntryData>(); var domainOfExpertiseDao = container.Resolve <IDomainOfExpertiseDao>(); var logEntryChangeLogItemDao = container.Resolve <ILogEntryChangelogItemDao>(); var domainOfExpertises = domainOfExpertiseDao.Read(transaction, "SiteDirectory", domains).ToList(); foreach (var changeNotificationSubscription in changeNotificationSubscriptionUserPreference.ChangeNotificationSubscriptions) { var changeNotificationFilter = this.CreateChangeLogNotificationFilter(changeNotificationSubscription, domainOfExpertises); foreach (var modelLogEntry in modelLogEntries.OrderBy(x => x.CreatedOn)) { if (changeNotificationFilter.CheckFilter(modelLogEntry)) { var modelLogEntryData = new ModelLogEntryData(modelLogEntry); var addModelLogEntryData = false; var logEntryChangeLogItems = logEntryChangeLogItemDao.Read(transaction, engineeringModelPartition, modelLogEntry.LogEntryChangelogItem).ToList(); foreach (var logEntryChangelogItem in logEntryChangeLogItems) { if (changeNotificationFilter.CheckFilter(logEntryChangelogItem)) { addModelLogEntryData = true; modelLogEntryData.TryAddLogEntryChangelogData(logEntryChangelogItem, changeNotificationSubscription); } } if (addModelLogEntryData) { modelLogEntryDataList.Add(modelLogEntryData); } } } } return(modelLogEntryDataList); }
/// <summary> /// Create an <see cref="IEnumerable{T}"/> of type <see cref="ChangelogSection"/>s to be used to compose the email body /// </summary> /// <param name="transaction"> /// The current <see cref="NpgsqlTransaction"/> to the database. /// </param> /// <param name="container"> /// The <see cref="IContainer"/> used to resolve injectable objects /// </param> /// <param name="engineeringModelIid"> /// The <see cref="EngineeringModel.Iid"/> property of the related <see cref="EngineeringModel"/> /// </param> /// <param name="person"> /// The <see cref="Person"/> for whom to compose the email /// </param> /// <param name="changeNotificationSubscriptionUserPreference"> /// The <see cref="ChangeNotificationSubscriptionUserPreference"/> that contains the change notification subscriptions /// </param> /// <param name="startDateTime"> /// The start <see cref="DateTime"/> of the period we want to collect change log rows for. /// </param> /// <param name="endDateTime"> /// The end <see cref="DateTime"/> of the period we want to collect change log rows for. /// </param> /// <returns> /// An <see cref="IEnumerable{T}"/> of type <see cref="ChangelogSection"/>s /// </returns> public IEnumerable <ChangelogSection> CreateChangelogSections( NpgsqlTransaction transaction, IContainer container, Guid engineeringModelIid, Person person, ChangeNotificationSubscriptionUserPreference changeNotificationSubscriptionUserPreference, DateTime startDateTime, DateTime endDateTime) { var partition = $"EngineeringModel_{engineeringModelIid.ToString().Replace("-", "_")}"; // if a model does not exist anymore, do not send report var engineeringModelSetupDao = container.Resolve <IEngineeringModelSetupDao>(); var engineeringModelSetup = engineeringModelSetupDao.Read(transaction, "SiteDirectory") .FirstOrDefault(x => x.EngineeringModelIid == engineeringModelIid); if (engineeringModelSetup == null) { yield return(this.CreateEngineeringModelNotFoundSection(changeNotificationSubscriptionUserPreference)); yield break; } // if a user is no longer a participant in a model, or if the participant is not active, then do not send report var participantDao = container.Resolve <IParticipantDao>(); var participants = participantDao .Read(transaction, "SiteDirectory") .Where(x => x.Person == person.Iid && x.IsActive) .ToList(); if (!participants.Any()) { yield return(this.CreateParticipantNotActiveSection(engineeringModelSetup)); yield break; } var engineeringModelParticipants = participants .Where(x => engineeringModelSetup.Participant.Contains(x.Iid)) .ToList(); if (!engineeringModelParticipants.Any()) { yield return(this.CreateNoEngineeringModelParticipantSection(engineeringModelSetup)); yield break; } var domains = participants .SelectMany(x => x.Domain) .Distinct() .ToList(); if (!domains.Any()) { yield return(this.CreateNoDomainOfExpertiseSection(engineeringModelSetup)); yield break; } var modelLogEntryDao = container.Resolve <IModelLogEntryDao>(); var modelLogEntries = modelLogEntryDao .Read(transaction, partition) .Where(x => x.ModifiedOn >= startDateTime && x.ModifiedOn < endDateTime) .ToList(); if (!modelLogEntries.Any() || !modelLogEntries.SelectMany(x => x.LogEntryChangelogItem).Any()) { yield return(this.CreateNoModelLogEntriesSection(engineeringModelSetup)); yield break; } if (!modelLogEntries.Any(x => x.AffectedDomainIid.Intersect(domains).Any())) { yield return(this.CreateNoRelevantChangesFoundSection(engineeringModelSetup)); yield break; } var filteredModelLogEntries = this.FilterDomains(modelLogEntries, domains); var modelLogEntryDataCreator = container.Resolve <IModelLogEntryDataCreator>(); var modelLogEntryData = modelLogEntryDataCreator.Create(transaction, partition, container, filteredModelLogEntries, domains, changeNotificationSubscriptionUserPreference); var changeNotificationSubscriptionDataGroups = modelLogEntryData .SelectMany(x => x.LogEntryChangelogItemData .SelectMany(y => y.ChangeNotificationSubscriptionData)) .GroupBy(x => x.ChangeNotificationSubscription, x => x.LogEntryChangelogItemData) .OrderBy(x => x.Key.ChangeNotificationSubscriptionType) .ThenBy(x => x.Key.ClassKind) .ThenBy(x => x.Key.Name); foreach (var changeNotificationSubscriptionGroup in changeNotificationSubscriptionDataGroups) { var changeNotificationSubscriptionData = changeNotificationSubscriptionGroup.Key; var subTitle = $"{changeNotificationSubscriptionData.Name} / {changeNotificationSubscriptionData.ClassKind} / {changeNotificationSubscriptionData.ChangeNotificationSubscriptionType}"; var descriptionBuilder = new StringBuilder(); foreach (var logEntryChangelogItemData in changeNotificationSubscriptionGroup.OrderBy(x => x.ModelLogEntryData.ModifiedOn)) { descriptionBuilder.AppendLine($"{logEntryChangelogItemData.ModelLogEntryData.ModifiedOn}"); descriptionBuilder.AppendLine($"{logEntryChangelogItemData.ModelLogEntryData.JustificationText}"); descriptionBuilder.AppendLine($"{logEntryChangelogItemData.ChangelogKind}"); descriptionBuilder.AppendLine($"{logEntryChangelogItemData.ChangeDescription}"); descriptionBuilder.AppendLine(""); } yield return(new ChangelogSection($"{engineeringModelSetup.Name}", subTitle, descriptionBuilder.ToString())); } }