Skip to content

Commit d3142d9

Browse files
authored
Merge pull request #1646 from bcgov/dev
Dev
2 parents b555a0c + 19424c3 commit d3142d9

131 files changed

Lines changed: 14679 additions & 1412 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

applications/Unity.GrantManager/modules/Unity.Flex/src/Unity.Flex.Application/Worksheets/Collectors/BCAddressCollector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.Text.Json;
55
using System.Threading.Tasks;
66
using Unity.Flex.Worksheets.Values;
7-
using Unity.GrantManager.Integration.Geocoder;
7+
using Unity.GrantManager.Integrations.Geocoder;
88

99
namespace Unity.Flex.Worksheets.Collectors
1010
{

applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Application/EmailNotificaions/EmailNotificationService.cs

Lines changed: 35 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using Microsoft.AspNetCore.Authorization;
2-
using Microsoft.AspNetCore.Http;
3-
using Microsoft.Extensions.Configuration;
42
using Microsoft.Extensions.Logging;
53
using System;
64
using System.Collections.Generic;
@@ -23,49 +21,31 @@
2321
using Volo.Abp.Domain.Entities;
2422
using Volo.Abp.Features;
2523
using Volo.Abp.SettingManagement;
24+
using Microsoft.AspNetCore.Http;
2625
using Volo.Abp.Users;
26+
using Unity.GrantManager.Notifications;
2727

2828
namespace Unity.Notifications.EmailNotifications;
2929

30-
3130
[Dependency(ReplaceServices = false)]
3231
[ExposeServices(typeof(EmailNotificationService), typeof(IEmailNotificationService))]
33-
public class EmailNotificationService : ApplicationService, IEmailNotificationService
34-
{
35-
private readonly IChesClientService _chesClientService;
36-
private readonly IConfiguration _configuration;
37-
private readonly EmailQueueService _emailQueueService;
38-
private readonly IEmailLogsRepository _emailLogsRepository;
39-
private readonly IExternalUserLookupServiceProvider _externalUserLookupServiceProvider;
40-
private readonly ISettingManager _settingManager;
41-
private readonly IFeatureChecker _featureChecker;
42-
private readonly IHttpContextAccessor _httpContextAccessor;
43-
44-
public EmailNotificationService(
32+
#pragma warning disable S107 // Methods should not have too many parameters
33+
public class EmailNotificationService(
34+
INotificationsAppService notificationAppService,
4535
IEmailLogsRepository emailLogsRepository,
46-
IConfiguration configuration,
4736
IChesClientService chesClientService,
4837
EmailQueueService emailQueueService,
4938
IExternalUserLookupServiceProvider externalUserLookupServiceProvider,
5039
ISettingManager settingManager,
5140
IFeatureChecker featureChecker,
52-
IHttpContextAccessor httpContextAccessor
53-
)
54-
{
55-
_emailLogsRepository = emailLogsRepository;
56-
_configuration = configuration;
57-
_chesClientService = chesClientService;
58-
_emailQueueService = emailQueueService;
59-
_externalUserLookupServiceProvider = externalUserLookupServiceProvider;
60-
_settingManager = settingManager;
61-
_featureChecker = featureChecker;
62-
_httpContextAccessor = httpContextAccessor;
63-
}
41+
IHttpContextAccessor httpContextAccessor) : ApplicationService, IEmailNotificationService
42+
#pragma warning restore S107 // Methods should not have too many parameters
43+
{
6444

6545
public async Task DeleteEmail(Guid id)
6646
{
67-
await _emailLogsRepository.DeleteAsync(id);
68-
}
47+
await emailLogsRepository.DeleteAsync(id);
48+
}
6949

7050
public async Task<int> GetEmailsChesWithNoResponseCountAsync()
7151
{
@@ -77,7 +57,7 @@ public async Task<int> GetEmailsChesWithNoResponseCountAsync()
7757
(x.Status == EmailStatus.Initialized && x.CreationTime.AddMinutes(10) < dbNow);
7858

7959
// Fetch all email logs and apply the filter using LINQ
80-
var allEmailLogs = await _emailLogsRepository.GetListAsync();
60+
var allEmailLogs = await emailLogsRepository.GetListAsync();
8161
var emailLogs = allEmailLogs.Where(filter.Compile()).ToList();
8262

8363
// Ensure we're returning 0 if no logs are found
@@ -90,16 +70,16 @@ public async Task<int> GetEmailsChesWithNoResponseCountAsync()
9070
{
9171
return null;
9272
}
93-
94-
var emailObject = await GetEmailObjectAsync(emailTo, body, subject, emailFrom, "html", emailTemplateName, emailCC, emailBCC);
95-
EmailLog emailLog = await _emailLogsRepository.GetAsync(emailId);
73+
74+
var emailObject = await GetEmailObjectAsync(emailTo, body, subject, emailFrom, "html", emailTemplateName);
75+
EmailLog emailLog = await emailLogsRepository.GetAsync(emailId);
9676
emailLog = UpdateMappedEmailLog(emailLog, emailObject);
9777
emailLog.ApplicationId = applicationId;
9878
emailLog.Id = emailId;
9979
emailLog.Status = status ?? EmailStatus.Initialized;
10080

10181
// When being called here the current tenant is in context - verified by looking at the tenant id
102-
EmailLog loggedEmail = await _emailLogsRepository.UpdateAsync(emailLog, autoSave: true);
82+
EmailLog loggedEmail = await emailLogsRepository.UpdateAsync(emailLog, autoSave: true);
10383
return loggedEmail;
10484
}
10585

@@ -122,7 +102,7 @@ public async Task<int> GetEmailsChesWithNoResponseCountAsync()
122102
emailLog.Status = status ?? EmailStatus.Initialized;
123103

124104
// When being called here the current tenant is in context - verified by looking at the tenant id
125-
EmailLog loggedEmail = await _emailLogsRepository.InsertAsync(emailLog, autoSave: true);
105+
EmailLog loggedEmail = await emailLogsRepository.InsertAsync(emailLog, autoSave: true);
126106
return loggedEmail;
127107
}
128108

@@ -131,21 +111,19 @@ protected virtual async Task NotifyTeamsChannel(string chesEmailError)
131111
string? envInfo = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
132112
string activityTitle = "CHES Email error: " + chesEmailError;
133113
string activitySubtitle = "Environment: " + envInfo;
134-
string teamsChannel = _configuration["Notifications:TeamsNotificationsWebhook"] ?? "";
135-
List<Fact> facts = new() { };
136-
await TeamsNotificationService.PostToTeamsAsync(teamsChannel, activityTitle, activitySubtitle, facts);
114+
await notificationAppService.PostToTeamsAsync(activityTitle, activitySubtitle);
137115
}
138116

139117
public async Task<HttpResponseMessage> SendCommentNotification(EmailCommentDto input)
140118
{
141119
HttpResponseMessage res = new();
142120
try
143121
{
144-
if (await _featureChecker.IsEnabledAsync("Unity.Notifications"))
122+
if (await featureChecker.IsEnabledAsync("Unity.Notifications"))
145123
{
146124
var defaultFromAddress = await SettingProvider.GetOrNullAsync(NotificationsSettings.Mailing.DefaultFromAddress);
147125
var scheme = "https";
148-
var request = _httpContextAccessor.HttpContext?.Request;
126+
var request = httpContextAccessor.HttpContext?.Request;
149127

150128
if (request == null)
151129
{
@@ -211,7 +189,6 @@ public async Task<HttpResponseMessage> SendCommentNotification(EmailCommentDto i
211189
return res;
212190
}
213191

214-
215192
/// <summary>
216193
/// Send Email Notfication
217194
/// </summary>
@@ -238,8 +215,8 @@ public async Task<HttpResponseMessage> SendEmailNotification(string emailTo, str
238215

239216
}
240217
// Send the email using the CHES client service
241-
var emailObject = await GetEmailObjectAsync(emailTo, body, subject, emailFrom, emailBodyType, emailTemplateName, emailCC, emailBCC);
242-
var response = await _chesClientService.SendAsync(emailObject);
218+
var emailObject = await GetEmailObjectAsync(emailTo, body, subject, emailFrom, emailBodyType, emailTemplateName);
219+
var response = await chesClientService.SendAsync(emailObject);
243220

244221
// Assuming SendAsync returns a HttpResponseMessage or equivalent:
245222
return response;
@@ -259,7 +236,7 @@ public async Task<HttpResponseMessage> SendEmailNotification(string emailTo, str
259236
EmailLog emailLog = new EmailLog();
260237
try
261238
{
262-
emailLog = await _emailLogsRepository.GetAsync(id);
239+
emailLog = await emailLogsRepository.GetAsync(id);
263240
}
264241
catch (EntityNotFoundException ex)
265242
{
@@ -272,7 +249,7 @@ public async Task<HttpResponseMessage> SendEmailNotification(string emailTo, str
272249
[Authorize]
273250
public virtual async Task<List<EmailHistoryDto>> GetHistoryByApplicationId(Guid applicationId)
274251
{
275-
var entityList = await _emailLogsRepository.GetByApplicationIdAsync(applicationId);
252+
var entityList = await emailLogsRepository.GetByApplicationIdAsync(applicationId);
276253
var dtoList = ObjectMapper.Map<List<EmailLog>, List<EmailHistoryDto>>(entityList);
277254

278255
var sentByUserIds = dtoList
@@ -284,7 +261,7 @@ public virtual async Task<List<EmailHistoryDto>> GetHistoryByApplicationId(Guid
284261

285262
foreach (var userId in sentByUserIds)
286263
{
287-
var userInfo = await _externalUserLookupServiceProvider.FindByIdAsync(userId);
264+
var userInfo = await externalUserLookupServiceProvider.FindByIdAsync(userId);
288265
if (userInfo != null)
289266
{
290267
userDictionary[userId] = ObjectMapper.Map<IUserData, EmailHistoryUserDto>(userInfo);
@@ -313,10 +290,18 @@ public async Task SendEmailToQueue(EmailLog emailLog)
313290
emailNotificationEvent.Id = emailLog.Id;
314291
emailNotificationEvent.TenantId = emailLog.TenantId;
315292
emailNotificationEvent.RetryAttempts = emailLog.RetryAttempts;
316-
await _emailQueueService.SendToEmailEventQueueAsync(emailNotificationEvent);
293+
await emailQueueService.SendToEmailEventQueueAsync(emailNotificationEvent);
317294
}
318295

319-
protected virtual async Task<dynamic> GetEmailObjectAsync(string emailTo, string body, string subject, string? emailFrom, string? emailBodyType, string? emailTemplateName, string? emailCC = null, string? emailBCC = null)
296+
protected virtual async Task<dynamic> GetEmailObjectAsync(
297+
string emailTo,
298+
string body,
299+
string subject,
300+
string? emailFrom,
301+
string? emailBodyType,
302+
string? emailTemplateName,
303+
string? emailCC = null,
304+
string? emailBCC = null)
320305
{
321306
var toList = emailTo.ParseEmailList() ?? [];
322307
var ccList = emailCC.ParseEmailList();
@@ -365,7 +350,7 @@ private async Task UpdateTenantSettings(string settingKey, string valueString)
365350
{
366351
if (!valueString.IsNullOrWhiteSpace())
367352
{
368-
await _settingManager.SetForCurrentTenantAsync(settingKey, valueString);
353+
await settingManager.SetForCurrentTenantAsync(settingKey, valueString);
369354
}
370355
}
371356
}

applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Application/Events/EmailNotificationHandler.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ internal class EmailNotificationHandler(
1515
IEmailNotificationService emailNotificationService,
1616
IFeatureChecker featureChecker) : ILocalEventHandler<EmailNotificationEvent>, ITransientDependency
1717
{
18-
private const string GRANT_APPLICATION_UPDATE_SUBJECT = "Grant Application Update";
1918
private const string FAILED_PAYMENTS_SUBJECT = "CAS Payment Failure Notification";
2019

2120
public async Task HandleEventAsync(EmailNotificationEvent eventData)

applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Application/Integrations/Ches/ChesClientOptions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
{
33
public class ChesClientOptions
44
{
5-
public string ChesUrl { get; set; } = string.Empty;
6-
public string ChesTokenUrl { get; set; } = string.Empty;
75
public string ChesClientId { get; set; } = string.Empty;
86
public string ChesClientSecret { get; set; } = string.Empty;
97
}
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,58 @@
11
using Volo.Abp;
22
using System.Threading.Tasks;
3-
using System.Text.Json;
43
using Unity.Modules.Shared.Integrations;
54
using Unity.Modules.Shared.Http;
65
using Volo.Abp.Application.Services;
76
using Microsoft.Extensions.Options;
87
using Volo.Abp.DependencyInjection;
98
using System.Net.Http;
109
using Volo.Abp.Caching;
10+
using Unity.GrantManager.Integrations;
1111

1212
namespace Unity.Notifications.Integrations.Ches
1313
{
1414
[IntegrationService]
1515
[RemoteService(false, Name = "Ches")]
1616
[ExposeServices(typeof(ChesClientService), typeof(IChesClientService))]
17-
public class ChesClientService : ApplicationService, IChesClientService
17+
public class ChesClientService(
18+
IDistributedCache<TokenValidationResponse, string> chesTokenCache,
19+
IResilientHttpRequest resilientHttpRequest,
20+
IEndpointManagementAppService endpointManagementAppService,
21+
IHttpClientFactory httpClientFactory,
22+
IOptions<ChesClientOptions> chesClientOptions
23+
) : ApplicationService, IChesClientService
1824
{
19-
private readonly IHttpClientFactory _httpClientFactory;
20-
private readonly IResilientHttpRequest _resilientRestClient;
21-
private readonly IOptions<ChesClientOptions> _chesClientOptions;
22-
private readonly IDistributedCache<TokenValidationResponse, string> _chesTokenCache;
23-
24-
public ChesClientService(
25-
IDistributedCache<TokenValidationResponse, string> chesTokenCache,
26-
IResilientHttpRequest resilientHttpRequest,
27-
IHttpClientFactory httpClientFactory,
28-
IOptions<ChesClientOptions> chesClientOptions)
25+
public async Task<HttpResponseMessage?> SendAsync(object emailRequest)
2926
{
30-
_resilientRestClient = resilientHttpRequest;
31-
_chesClientOptions = chesClientOptions;
32-
_httpClientFactory = httpClientFactory;
33-
_chesTokenCache = chesTokenCache;
27+
string authToken = await GetAuthTokenAsync();
28+
string notificationsApiUrl = await endpointManagementAppService.GetUgmUrlByKeyNameAsync(DynamicUrlKeyNames.NOTIFICATION_API_BASE);
29+
var resource = $"{notificationsApiUrl}/email";
30+
31+
// Pass the object directly; ResilientHttpRequest will serialize it to JSON
32+
var response = await resilientHttpRequest.HttpAsync(
33+
HttpMethod.Post,
34+
resource,
35+
emailRequest,
36+
authToken
37+
);
38+
39+
return response;
3440
}
3541

36-
public async Task<HttpResponseMessage?> SendAsync(object emailRequest)
42+
private async Task<string> GetAuthTokenAsync()
3743
{
38-
ClientOptions clientOptions = new ClientOptions
44+
string notificationsAuthUrl = await endpointManagementAppService.GetUgmUrlByKeyNameAsync(DynamicUrlKeyNames.NOTIFICATION_AUTH);
45+
46+
ClientOptions clientOptions = new()
3947
{
40-
Url = _chesClientOptions.Value.ChesTokenUrl,
41-
ClientId = _chesClientOptions.Value.ChesClientId,
42-
ClientSecret = _chesClientOptions.Value.ChesClientSecret,
48+
Url = notificationsAuthUrl,
49+
ClientId = chesClientOptions.Value.ChesClientId,
50+
ClientSecret = chesClientOptions.Value.ChesClientSecret,
4351
ApiKey = "ChesApiKey"
4452
};
4553

46-
TokenService tokenService = new(_httpClientFactory, _chesTokenCache, Logger);
47-
var authToken = await tokenService.GetAuthTokenAsync(clientOptions);
48-
var resource = $"{_chesClientOptions.Value.ChesUrl}/email";
49-
string jsonString = JsonSerializer.Serialize(emailRequest);
50-
var response = await _resilientRestClient.HttpAsyncWithBody(HttpMethod.Post, resource, jsonString, authToken);
51-
return response;
54+
TokenService tokenService = new(httpClientFactory, chesTokenCache, Logger);
55+
return await tokenService.GetAuthTokenAsync(clientOptions);
5256
}
5357
}
5458
}

0 commit comments

Comments
 (0)