changeLogSections)
+ {
+ var stringBuilder = new StringBuilder();
+
+ foreach (var section in changeLogSections)
+ {
+ stringBuilder.AppendLine("
");
+ stringBuilder.AppendLine($"{section.Title}
");
+ stringBuilder.AppendLine($"{section.SubTitle}
");
+ stringBuilder.AppendLine($"{section.Description.Replace(Environment.NewLine, "
")}
");
+ }
+
+ return stringBuilder.ToString();
+ }
+
+ ///
+ /// Create an of type s to be used to compose the email body
+ ///
+ ///
+ /// The current to the database.
+ ///
+ ///
+ /// The used to resolve injectable objects
+ ///
+ ///
+ /// The property of the related
+ ///
+ ///
+ /// The for whom to compose the email
+ ///
+ ///
+ /// The that contains the change notification subscriptions
+ ///
+ ///
+ /// The start of the period we want to collect change log rows for.
+ ///
+ ///
+ /// The end of the period we want to collect change log rows for.
+ ///
+ ///
+ /// An of type s
+ ///
+ public IEnumerable 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();
+
+ 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();
+
+ 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();
+
+ 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();
+
+ 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());
+ }
+ }
+
+ ///