Skip to content

Commit

Permalink
Funding Notfications (#68)
Browse files Browse the repository at this point in the history
* Changes to send notification to EA and Primary contact on change of Funding record chnage to "FA Signature Pending"

* Changes doneto cache the communication type

* Removed the individual method setCommunicationtype
  • Loading branch information
bcgov-hl authored Apr 11, 2024
1 parent 43ec5e3 commit 5a6f775
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 58 deletions.
3 changes: 3 additions & 0 deletions OFM.Infrastructure.WebAPI/Extensions/SetupInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public static class Emails

public const Int16 SendNotificationsId = 205;
public const string SendNotificationsName = "Send bulk emails on-demand";

public const Int16 SendFundingNotificationsId = 210;
public const string SendFundingNotificationsName = "Create emails on Status change of Funding record to FASignaturePending when a Ministry EA approves the funding";
}

public static class Fundings
Expand Down
7 changes: 7 additions & 0 deletions OFM.Infrastructure.WebAPI/Models/DataverseModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ public record D365Template
public string? safehtml { get; set; }
public string? body { get; set; }
public string? templateid { get; set; }
public string? templatecode { get; set; }
}

public record D365Email
Expand Down Expand Up @@ -259,6 +260,12 @@ public record Email_Activity_Parties
public string? addressused { get; set; }
}

public record D365CommunicationType
{
public string? ofm_communication_typeid { get; set; }
public Int16? ofm_communication_type_number { get; set; }
}

#region External Parameters

#endregion
2 changes: 2 additions & 0 deletions OFM.Infrastructure.WebAPI/Models/Fundings/Fundings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ public class Application : ofm_application
public new decimal? ofm_costs_property_insurance { get; set; }
public new decimal? ofm_costs_supplies { get; set; }
public new decimal? ofm_costs_strata_fee { get; set; }
public new Guid? _ofm_contact_value { get; set; }
public new Guid? _ofm_expense_authority_value { get; set; }

public new D365Facility? ofm_facility { get; set; }
}
Expand Down
3 changes: 3 additions & 0 deletions OFM.Infrastructure.WebAPI/Models/SettingsModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public record NotificationSettings
public required EmailTemplate[] EmailTemplates { get; set; }
public required CommunicationTypes CommunicationTypes { get; set; }
public required SafeList EmailSafeList { get; set; }
public required string fundingUrl { get; set; }
public required string fundingTabUrl { get; set; }


public record SafeList
{
Expand Down
2 changes: 2 additions & 0 deletions OFM.Infrastructure.WebAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
services.AddScoped<ID365ProcessProvider, P100InactiveRequestProvider>();
services.AddScoped<ID365ProcessProvider, P200EmailReminderProvider>();
services.AddScoped<ID365ProcessProvider, P205SendNotificationProvider>();
services.AddScoped<ID365ProcessProvider, P210CreateFundingNotificationProvider>();
services.AddScoped<ID365ProcessProvider, P300BaseFundingProvider>();
services.AddScoped<ID365ProcessProvider, P305SupplementaryFundingProvider>();
services.AddScoped<ID365ProcessProvider, P310CalculateDefaultAllocationProvider>();
Expand All @@ -65,6 +66,7 @@
services.AddScoped<ID365BatchProvider, BatchProvider>();
services.AddScoped<ID365BatchProvider, ContactEditProvider>();
services.AddScoped<IFundingRepository, FundingRepository>();
services.AddScoped<IEmailRepository, EmailRepository>();

services.AddD365HttpClient(builder.Configuration);
services.AddMvcCore().AddApiExplorer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using ECC.Core.DataContext;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using OFM.Infrastructure.WebAPI.Extensions;
using OFM.Infrastructure.WebAPI.Messages;
using OFM.Infrastructure.WebAPI.Models.Fundings;
using OFM.Infrastructure.WebAPI.Services.AppUsers;
using OFM.Infrastructure.WebAPI.Services.D365WebApi;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Net;
using OFM.Infrastructure.WebAPI.Models;

namespace OFM.Infrastructure.WebAPI.Services.Processes.Fundings;

public interface IEmailRepository
{
Task<IEnumerable<D365CommunicationType>> LoadCommunicationTypeAsync();
}

public class EmailRepository(ID365AppUserService appUserService, ID365WebApiService service, ID365DataService dataService, ILoggerFactory loggerFactory) : IEmailRepository
{
private readonly ILogger _logger = loggerFactory.CreateLogger(LogCategory.Process);
private readonly ID365DataService _dataService = dataService;
private readonly ID365AppUserService _appUserService = appUserService;
private readonly ID365WebApiService _d365webapiservice = service;
private Guid? _fundingId;

#region Pre-Defined Queries

private string CommunicationTypeRequestUri
{
get
{
// For reference only
var fetchXml = """
<fetch distinct="true" no-lock="true">
<entity name="ofm_communication_type">
<attribute name="ofm_communication_typeid" />
<attribute name="ofm_communication_type_number" />
<attribute name="statecode" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</entity>
</fetch>
""";

var requestUri = $"""
ofm_communication_types?fetchXml={WebUtility.UrlEncode(fetchXml)}
""";

return requestUri;
}
}
#endregion

public async Task<IEnumerable<D365CommunicationType>> LoadCommunicationTypeAsync()
{
var localdata = await _dataService.FetchDataAsync(CommunicationTypeRequestUri, "CommunicationTypes");
var deserializedData = localdata.Data.Deserialize<List<D365CommunicationType>>(Setup.s_writeOptionsForLogs);

return await Task.FromResult(deserializedData!); ;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using OFM.Infrastructure.WebAPI.Models;
using OFM.Infrastructure.WebAPI.Services.AppUsers;
using OFM.Infrastructure.WebAPI.Services.D365WebApi;
using OFM.Infrastructure.WebAPI.Services.Processes.Fundings;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
Expand All @@ -20,19 +21,21 @@ public class P200EmailReminderProvider : ID365ProcessProvider
private readonly ID365AppUserService _appUserService;
private readonly ID365WebApiService _d365webapiservice;
private readonly D365AuthSettings _d365AuthSettings;
private readonly IEmailRepository _emailRepository;
private readonly ILogger _logger;
private readonly TimeProvider _timeProvider;
private ProcessData? _data;
private string[] _activeCommunicationTypes = [];
private string[] _communicationTypesForUnreadReminders = [];
private string _requestUri = string.Empty;

public P200EmailReminderProvider(IOptionsSnapshot<NotificationSettings> notificationSettings, IOptionsSnapshot<D365AuthSettings> d365AuthSettings, ID365AppUserService appUserService, ID365WebApiService d365WebApiService, ILoggerFactory loggerFactory, TimeProvider timeProvider)
public P200EmailReminderProvider(IOptionsSnapshot<NotificationSettings> notificationSettings, IOptionsSnapshot<D365AuthSettings> d365AuthSettings, IEmailRepository emailRepository, ID365AppUserService appUserService, ID365WebApiService d365WebApiService, ILoggerFactory loggerFactory, TimeProvider timeProvider)
{
_notificationSettings = notificationSettings.Value;
_appUserService = appUserService;
_d365webapiservice = d365WebApiService;
_d365AuthSettings = d365AuthSettings.Value;
_emailRepository = emailRepository;
_logger = loggerFactory.CreateLogger(LogCategory.Process);
_timeProvider = timeProvider;
}
Expand Down Expand Up @@ -147,8 +150,14 @@ public async Task<ProcessData> GetDataAsync()

public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService, ID365WebApiService d365WebApiService, ProcessParameter processParams)
{
await SetupCommunicationTypes();

IEnumerable<D365CommunicationType> _communicationType = await _emailRepository!.LoadCommunicationTypeAsync();
_activeCommunicationTypes = _communicationType.ToArray()
.Select(comm_type => string.Concat("'", comm_type.ofm_communication_typeid, "'"))
.ToArray<string>();
_communicationTypesForUnreadReminders = _communicationType.ToArray().Where(type => type.ofm_communication_type_number == _notificationSettings.CommunicationTypes.ActionRequired ||
type.ofm_communication_type_number == _notificationSettings.CommunicationTypes.DebtLetter ||
type.ofm_communication_type_number == _notificationSettings.CommunicationTypes.FundingAgreement)
.Select(type => type.ofm_communication_typeid!.ToString())!.ToArray<string>();
if (!_activeCommunicationTypes.Any())
throw new Exception("Communication Types are missing.");

Expand Down Expand Up @@ -278,59 +287,5 @@ private bool IsNewAndUnread(D365Email email, Range<DateTime> todayRange)
return false;
}

private async Task SetupCommunicationTypes()
{
if (!_activeCommunicationTypes.Any())
{
var fetchXml = """
<fetch distinct="true" no-lock="true">
<entity name="ofm_communication_type">
<attribute name="ofm_communication_typeid" />
<attribute name="ofm_communication_type_number" />
<attribute name="ofm_name" />
<attribute name="statecode" />
<attribute name="statuscode" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</entity>
</fetch>
""";

var requestUri = $"""
ofm_communication_types?fetchXml={WebUtility.UrlEncode(fetchXml)}
""";

var response = await _d365webapiservice.SendRetrieveRequestAsync(_appUserService.AZSystemAppUser, requestUri);

if (!response.IsSuccessStatusCode)
{
var responseBody = await response.Content.ReadAsStringAsync();
_logger.LogError(CustomLogEvent.Process, "Failed to query the communcation types with a server error {responseBody}", responseBody.CleanLog());
}

var jsonObject = await response.Content.ReadFromJsonAsync<JsonObject>();

JsonNode d365Result = string.Empty;
if (jsonObject?.TryGetPropertyValue("value", out var currentValue) == true)
{
if (currentValue?.AsArray().Count == 0)
{
_logger.LogInformation(CustomLogEvent.Process, "No communcation types found with query {requestUri}", requestUri);
}
d365Result = currentValue!;
}

_activeCommunicationTypes = d365Result.AsArray()
.Select(comm_type => string.Concat("'", comm_type?["ofm_communication_typeid"], "'"))
.ToArray<string>();
_communicationTypesForUnreadReminders = d365Result.AsArray().Where(type => type?["ofm_communication_type_number"]?.ToString() == _notificationSettings.CommunicationTypes.ActionRequired.ToString() ||
type?["ofm_communication_type_number"]?.ToString() == _notificationSettings.CommunicationTypes.DebtLetter.ToString() ||
type?["ofm_communication_type_number"]?.ToString() == _notificationSettings.CommunicationTypes.FundingAgreement.ToString())
.Select(type => type?["ofm_communication_typeid"]!.ToString())!.ToArray<string>();

}
}

#endregion
}
Loading

0 comments on commit 5a6f775

Please sign in to comment.