diff --git a/src/backend/function/Fusion.Resources.Functions/ApiClients/ApiModels/LineOrg.cs b/src/backend/function/Fusion.Resources.Functions/ApiClients/ApiModels/LineOrg.cs index 6545f6744..e8e4e11bf 100644 --- a/src/backend/function/Fusion.Resources.Functions/ApiClients/ApiModels/LineOrg.cs +++ b/src/backend/function/Fusion.Resources.Functions/ApiClients/ApiModels/LineOrg.cs @@ -30,6 +30,7 @@ public class Manager } public class LineOrgPerson { + public string? DepartmentSapId { get; set; } [JsonProperty("azureUniqueId")] public string AzureUniqueId { get; set; } [JsonProperty("managerId")] public string ManagerId { get; set; } diff --git a/src/backend/function/Fusion.Resources.Functions/ApiClients/ILineOrgApiClient.cs b/src/backend/function/Fusion.Resources.Functions/ApiClients/ILineOrgApiClient.cs index 462970fb5..47e5427d3 100644 --- a/src/backend/function/Fusion.Resources.Functions/ApiClients/ILineOrgApiClient.cs +++ b/src/backend/function/Fusion.Resources.Functions/ApiClients/ILineOrgApiClient.cs @@ -6,6 +6,6 @@ namespace Fusion.Resources.Functions.ApiClients; public interface ILineOrgApiClient { - Task> GetOrgUnitDepartmentsAsync(); - Task> GetResourceOwnersFromFullDepartment(List fullDepartments); + Task> GetOrgUnitDepartmentsAsync(); + Task> GetResourceOwnersFromFullDepartment(List fullDepartments); } \ No newline at end of file diff --git a/src/backend/function/Fusion.Resources.Functions/ApiClients/LineOrgApiClient.cs b/src/backend/function/Fusion.Resources.Functions/ApiClients/LineOrgApiClient.cs index 3a1518fd5..0888cf739 100644 --- a/src/backend/function/Fusion.Resources.Functions/ApiClients/LineOrgApiClient.cs +++ b/src/backend/function/Fusion.Resources.Functions/ApiClients/LineOrgApiClient.cs @@ -19,33 +19,36 @@ public LineOrgApiClient(IHttpClientFactory httpClientFactory) lineOrgClient.Timeout = TimeSpan.FromMinutes(5); } - public async Task> GetOrgUnitDepartmentsAsync() + public async Task> GetOrgUnitDepartmentsAsync() { var data = - await lineOrgClient.GetAsJsonAsync>($"/org-units?$top={int.MaxValue}"); + await lineOrgClient.GetAsJsonAsync>($"/org-units?$top={int.MaxValue}"); return data.Value .Where(x => !string.IsNullOrEmpty(x.FullDepartment)) - .Select(x => x.FullDepartment!).ToList(); + .ToList(); } - public async Task> GetResourceOwnersFromFullDepartment(List fullDepartments) + public async Task> GetResourceOwnersFromFullDepartment(List fullDepartments) { var list = fullDepartments - .Select(l => $"'{l}'") + .Select(l => $"'{l.FullDepartment?.Replace("&", "%26")}'") .ToList() .Aggregate((a, b) => $"{a}, {b}"); var queryString = $"/lineorg/persons?$filter=fullDepartment in " + $"({list}) " + $"and isResourceOwner eq 'true'"; var resourceOwners = await lineOrgClient.GetAsJsonAsync(queryString); + foreach (var r in resourceOwners.Value) + r.DepartmentSapId = fullDepartments.FirstOrDefault(x => x.FullDepartment == r.FullDepartment)?.SapId; return resourceOwners.Value; } - internal class DepartmentRef + public class OrgUnits { public string? FullDepartment { get; set; } + public string? SapId { get; set; } } internal class InternalCollection diff --git a/src/backend/function/Fusion.Resources.Functions/Functions/InternalRequestsFunctions.cs b/src/backend/function/Fusion.Resources.Functions/Functions/InternalRequestsFunctions.cs index b9b4c88ae..4a2f27336 100644 --- a/src/backend/function/Fusion.Resources.Functions/Functions/InternalRequestsFunctions.cs +++ b/src/backend/function/Fusion.Resources.Functions/Functions/InternalRequestsFunctions.cs @@ -31,7 +31,7 @@ public async Task ReassignResourceAllocationRequestsWithInvalidDepartment([Timer log.LogTrace($"Next occurrences: {timer.FormatNextOccurrences(3)}"); var activeProjects = await resourcesClient.GetProjectsAsync(); - var activeDepartments = (await lineOrgClient.GetOrgUnitDepartmentsAsync()).ToList(); + var activeDepartments = (await lineOrgClient.GetOrgUnitDepartmentsAsync()).Select(o => o.FullDepartment).ToList(); foreach (var project in activeProjects) { diff --git a/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/Models/DTOs/ScheduledNotificationQueueDto.cs b/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/Models/DTOs/ScheduledNotificationQueueDto.cs index e68d50331..68d9ec7da 100644 --- a/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/Models/DTOs/ScheduledNotificationQueueDto.cs +++ b/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/Models/DTOs/ScheduledNotificationQueueDto.cs @@ -4,6 +4,7 @@ public class ScheduledNotificationQueueDto { public string AzureUniqueId { get; set; } public string FullDepartment { get; set; } + public string DepartmentSapId { get; set; } public NotificationRoleType Role { get; set; } } public enum NotificationRoleType diff --git a/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/ScheduledReportTimerTriggerFunction.cs b/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/ScheduledReportTimerTriggerFunction.cs index c4f842c0a..2b437ec1b 100644 --- a/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/ScheduledReportTimerTriggerFunction.cs +++ b/src/backend/function/Fusion.Resources.Functions/Functions/Notifications/ScheduledReportTimerTriggerFunction.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Azure.Messaging.ServiceBus; using Fusion.Resources.Functions.ApiClients; +using Fusion.Resources.Functions.ApiClients.ApiModels; using Fusion.Resources.Functions.Functions.Notifications.Models.DTOs; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Configuration; @@ -31,7 +32,7 @@ public ScheduledReportTimerTriggerFunction(ILineOrgApiClient lineOrgApiClient, [FunctionName("scheduled-report-timer-trigger-function")] public async Task RunAsync( - [TimerTrigger("0 0 0 * * MON", RunOnStartup = false)] + [TimerTrigger("0 0 8 * * MON", RunOnStartup = false)] TimerInfo scheduledReportTimer) { _logger.LogInformation( @@ -60,23 +61,19 @@ private async Task SendResourceOwnersToQueue(ServiceBusSender sender) { try { + var departments = await _lineOrgClient.GetOrgUnitDepartmentsAsync(); + if (departments == null || !departments.Any()) + throw new Exception("No departments found."); + // TODO: These resource-owners are handpicked to limit the scope of the project. - var resourceOwners = - await _lineOrgClient.GetResourceOwnersFromFullDepartment( - new List - { - "PDP PRD PMC PCA PCA1", - "PDP PRD PMC PCA PCA2", - "PDP PRD PMC PCA PCA3", - "PDP PRD PMC PCA PCA4", - "PDP PRD PMC PCA PCA5", - "PDP PRD PMC PCA PCA6", - "CFO FCOE PO CPC DA SOL" - }); + var selectedDepartments = departments + .Where(d => d.FullDepartment != null && d.FullDepartment.Contains("PRD")).Distinct().ToList(); + var resourceOwners = await GetLineOrgPersonsFromDepartmetnsChunked(selectedDepartments); + if (resourceOwners == null || !resourceOwners.Any()) throw new Exception("No resource-owners found."); - foreach (var resourceOwner in resourceOwners) + foreach (var resourceOwner in resourceOwners.DistinctBy(ro => ro.AzureUniqueId)) { try { @@ -106,6 +103,21 @@ await _lineOrgClient.GetResourceOwnersFromFullDepartment( } } + private async Task> GetLineOrgPersonsFromDepartmetnsChunked(List selectedDepartments) + { + var resourceOwners = new List(); + const int chuckSize = 10; + for (var i = 0; i < selectedDepartments.Count; i += chuckSize) + { + var chunk = selectedDepartments.Skip(i).Take(chuckSize).ToList(); + var chunkedResourceOwners = + await _lineOrgClient.GetResourceOwnersFromFullDepartment(chunk); + resourceOwners.AddRange(chunkedResourceOwners); + } + + return resourceOwners; + } + private async Task SendDtoToQueue(ServiceBusSender sender, ScheduledNotificationQueueDto dto) { var serializedDto = JsonConvert.SerializeObject(dto);