diff --git a/OFM.Infrastructure.WebAPI/Extensions/SetupInfo.cs b/OFM.Infrastructure.WebAPI/Extensions/SetupInfo.cs index 118a750a..ef298628 100644 --- a/OFM.Infrastructure.WebAPI/Extensions/SetupInfo.cs +++ b/OFM.Infrastructure.WebAPI/Extensions/SetupInfo.cs @@ -43,7 +43,7 @@ public static class Funding public static class ProviderProfile { public const Int16 VerifyGoodStandingId = 400; - public const string VerifyGoodStandingName = "Verify Good Standing Status for Organizations in batch"; + public const string VerifyGoodStandingName = "Verify Good Standing Status for Organization"; public const Int16 VerifyGoodStandingBatchId = 405; public const string VerifyGoodStandingBatchName = "Verify Good Standing Status for Organizations in batch"; diff --git a/OFM.Infrastructure.WebAPI/Models/DataverseModels.cs b/OFM.Infrastructure.WebAPI/Models/DataverseModels.cs index 989b5c08..3920dd60 100644 --- a/OFM.Infrastructure.WebAPI/Models/DataverseModels.cs +++ b/OFM.Infrastructure.WebAPI/Models/DataverseModels.cs @@ -194,6 +194,16 @@ public bool IsCompleted } } +public record D365Organization_Account +{ + public string? accountid { get; set; } + public string? name { get; set; } + public string? ofm_incorporation_number { get; set; } + public string? ofm_business_number { get; set; } + public int statecode { get; set; } + +} + public record FileMapping { public required string ofm_subject { get; set; } diff --git a/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P400VerifyGoodStandingProvider.cs b/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P400VerifyGoodStandingProvider.cs index b99d5059..39abc3aa 100644 --- a/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P400VerifyGoodStandingProvider.cs +++ b/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P400VerifyGoodStandingProvider.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Services; using OFM.Infrastructure.WebAPI.Extensions; using OFM.Infrastructure.WebAPI.Models; using OFM.Infrastructure.WebAPI.Services.AppUsers; @@ -24,7 +25,7 @@ public P400VerifyGoodStandingProvider(IOptionsSnapshot ApiKeyB _BCRegistrySettings = ApiKeyBCRegistry.Value.BCRegistryApi; _appUserService = appUserService; _d365webapiservice = d365WebApiService; - _logger = loggerFactory.CreateLogger(LogCategory.Process); ; + _logger = loggerFactory.CreateLogger(LogCategory.Process); _timeProvider = timeProvider; } @@ -38,11 +39,10 @@ public string RequestUri - - + + - @@ -99,44 +99,91 @@ public async Task RunProcessAsync(ID365AppUserService appUserService var startTime = _timeProvider.GetTimestamp(); - string? queryValue = (!String.IsNullOrEmpty(processParams?.Organization?.incorporationNumber)) ? - (_processParams?.Organization?.incorporationNumber)!.Trim() : (_processParams?.Organization?.legalName)!.Trim(); + var localData = await GetData(); - var legalType = "A,B,BC,BEN,C,CC,CCC,CEM,CP,CS,CUL,EPR,FI,FOR,GP,LIC,LIB,LL,LLC,LP,MF,PA,PAR,PFS,QA,QB,QC,QD,QE,REG,RLY,S,SB,SP,T,TMY,ULC,UQA,UQB,UQC,UQD,UQE,XCP,XL,XP,XS"; - var status = "active"; - var queryString = $"?query=value:{queryValue}::identifier:::bn:::name:" + - $"&categories=legalType:{legalType}::status:{status}"; + var deserializedData = JsonSerializer.Deserialize>(localData.Data.ToString()); - var path = $"{_BCRegistrySettings.RegistrySearchUrl}" + $"{queryString}"; + deserializedData?.ForEach(async organization => + { + String organizationId = organization.accountid; + String legalName = organization.name; + String incorporationNumber = organization.ofm_incorporation_number; + String businessNumber = organization.ofm_business_number; - var client = new HttpClient(); - var request = new HttpRequestMessage(HttpMethod.Get, path); - request.Headers.Add("Account-Id", "1"); - request.Headers.Add(_BCRegistrySettings.KeyName, _BCRegistrySettings.KeyValue); + string? queryValue = (!String.IsNullOrEmpty(incorporationNumber)) ? + incorporationNumber : legalName.Trim(); - var response = await client.SendAsync(request); - response.EnsureSuccessStatusCode(); + var legalType = "A,B,BC,BEN,C,CC,CCC,CEM,CP,CS,CUL,EPR,FI,FOR,GP,LIC,LIB,LL,LLC,LP,MF,PA,PAR,PFS,QA,QB,QC,QD,QE,REG,RLY,S,SB,SP,T,TMY,ULC,UQA,UQB,UQC,UQD,UQE,XCP,XL,XP,XS"; + var status = "active"; + var queryString = $"?query=value:{queryValue}::identifier:::bn:::name:" + + $"&categories=legalType:{legalType}::status:{status}"; - BCRegistrySearchResult? searchResult = await response.Content.ReadFromJsonAsync(); + var path = $"{_BCRegistrySettings.RegistrySearchUrl}" + $"{queryString}"; - if (searchResult is null || searchResult.searchResults.totalResults < 1) - { - // Todo: Add a new message for this scenario or try seach by name - _logger.LogError(CustomLogEvent.Process, "No results found."); - return ProcessResult.PartialSuccess(ProcessId, ["No records found."], 0, 0).SimpleProcessResult; - } + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Get, path); + request.Headers.Add("Account-Id", "1"); + request.Headers.Add(_BCRegistrySettings.KeyName, _BCRegistrySettings.KeyValue); - if (searchResult.searchResults.totalResults > 1) - { - // ToDo: Process and filter the result further - _logger.LogError(CustomLogEvent.Process, "More than one records returned. Please resolve this issue to ensure uniqueness"); - return ProcessResult.PartialSuccess(ProcessId, ["Multiple results returned."], 0, 0).SimpleProcessResult; - } + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + BCRegistrySearchResult? searchResult = await response.Content.ReadFromJsonAsync(); + + var responseBody = await response.Content.ReadAsStringAsync(); + + // Organization - Update + var goodStandingStatus = 3; // 1 - Good, 2 - No Good, 3 - Error + + // Integration Log - Create + var externalService = "BC Registries"; + var subject = string.Empty; + var logCategory = 1; // 1 - Info, 2 - Warning, 3 - Error, 4 - Critical + var message = $"{responseBody.CleanLog()}"; + + if (searchResult is null || searchResult.searchResults.totalResults < 1) + { + // Todo: Add a new message for this scenario or try seach by name + _logger.LogError(CustomLogEvent.Process, "No results found."); + + goodStandingStatus = 3; + logCategory = 3; + subject = "No results found"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.PartialSuccess(ProcessId, ["No records found."], 0, 0).SimpleProcessResult; + } + + if (searchResult.searchResults.totalResults > 1) + { + // ToDo: Process and filter the result further + _logger.LogError(CustomLogEvent.Process, "More than one records returned. Please resolve this issue to ensure uniqueness"); + + goodStandingStatus = 3; + logCategory = 3; + subject = "Multiple results returned"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.PartialSuccess(ProcessId, ["Multiple results returned."], 0, 0).SimpleProcessResult; + } + + if (searchResult.searchResults.totalResults == 1) + { + goodStandingStatus = searchResult.searchResults.results.First().goodStanding ? 1 : 2; // 1 - Good, 2 - No Good, 3 - Error + logCategory = 1; // 1 - Info, 2 - Warning, 3 - Error, 4 - Critical + subject = "One result found"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.Completed(ProcessId).SimpleProcessResult; + } - var statement = $"accounts({_processParams?.Organization?.organizationId.ToString()})"; + }); + return ProcessResult.Completed(ProcessId).SimpleProcessResult; + } + + private async Task UpdateOrganizationCreateIntegrationLog(ID365AppUserService appUserService, ID365WebApiService d365WebApiService, String organizationId, int goodStandingStatus, string subject, int category, string message, string externalService) + { + var statement = $"accounts({organizationId})"; var payload = new JsonObject { - { "ofm_good_standing_status", searchResult.searchResults.results.First().goodStanding ? 1 : 0}, + { "ofm_good_standing_status", goodStandingStatus}, { "ofm_good_standing_validated_on", DateTime.UtcNow } }; @@ -152,6 +199,17 @@ public async Task RunProcessAsync(ID365AppUserService appUserService return ProcessResult.Failure(ProcessId, new String[] { responseBody }, 0, 0).SimpleProcessResult; } + var entitySetName = "ofm_integration_logs"; + var payload2 = new JsonObject { + { "ofm_subject", subject }, + { "ofm_category", category}, + { "ofm_message", message}, + { "ofm_service_name", externalService}, + { "ofm_regardingid_account@odata.bind", $"/accounts({organizationId})"} + }; + var requestBody2 = JsonSerializer.Serialize(payload2); + var CreateResponse = await d365WebApiService.SendCreateRequestAsync(appUserService.AZSystemAppUser, entitySetName, requestBody2); + return ProcessResult.Completed(ProcessId).SimpleProcessResult; } } \ No newline at end of file diff --git a/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P405VerifyGoodStandingProviderBatch.cs b/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P405VerifyGoodStandingProviderBatch.cs index 034560f8..52c26ea4 100644 --- a/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P405VerifyGoodStandingProviderBatch.cs +++ b/OFM.Infrastructure.WebAPI/Services/Processes/ProviderProfile/P405VerifyGoodStandingProviderBatch.cs @@ -3,9 +3,11 @@ using OFM.Infrastructure.WebAPI.Models; using OFM.Infrastructure.WebAPI.Services.AppUsers; using OFM.Infrastructure.WebAPI.Services.D365WebApi; +using System; using System.Net; using System.Text.Json; using System.Text.Json.Nodes; +using System.Xml.Linq; namespace OFM.Infrastructure.WebAPI.Services.Processes.ProviderProfile; @@ -24,7 +26,7 @@ public P405VerifyGoodStandingBatchProvider(IOptionsSnapshot Ap _BCRegistrySettings = ApiKeyBCRegistry.Value.BCRegistryApi; _appUserService = appUserService; _d365webapiservice = d365WebApiService; - _logger = loggerFactory.CreateLogger(LogCategory.Process); ; + _logger = loggerFactory.CreateLogger(LogCategory.Process); _timeProvider = timeProvider; } @@ -35,18 +37,26 @@ public string RequestUri { get { + // var fetchXml = $""" - - + + - - + + - - - + + + + + + + + + + """; @@ -100,44 +110,91 @@ public async Task RunProcessAsync(ID365AppUserService appUserService var startTime = _timeProvider.GetTimestamp(); - string? queryValue = (!String.IsNullOrEmpty(processParams?.Organization?.incorporationNumber)) ? - (_processParams?.Organization?.incorporationNumber)!.Trim() : (_processParams?.Organization?.legalName)!.Trim(); + var localData = await GetData(); - var legalType = "A,B,BC,BEN,C,CC,CCC,CEM,CP,CS,CUL,EPR,FI,FOR,GP,LIC,LIB,LL,LLC,LP,MF,PA,PAR,PFS,QA,QB,QC,QD,QE,REG,RLY,S,SB,SP,T,TMY,ULC,UQA,UQB,UQC,UQD,UQE,XCP,XL,XP,XS"; - var status = "active"; - var queryString = $"?query=value:{queryValue}::identifier:::bn:::name:" + - $"&categories=legalType:{legalType}::status:{status}"; + var deserializedData = JsonSerializer.Deserialize>(localData.Data.ToString()); - var path = $"{_BCRegistrySettings.RegistrySearchUrl}" + $"{queryString}"; + deserializedData?.ForEach(async organization => + { + String organizationId = organization.accountid; + String legalName = organization.name; + String incorporationNumber = organization.ofm_incorporation_number; + String businessNumber = organization.ofm_business_number; - var client = new HttpClient(); - var request = new HttpRequestMessage(HttpMethod.Get, path); - request.Headers.Add("Account-Id", "1"); - request.Headers.Add(_BCRegistrySettings.KeyName, _BCRegistrySettings.KeyValue); + string? queryValue = (!String.IsNullOrEmpty(incorporationNumber)) ? + incorporationNumber : legalName.Trim(); - var response = await client.SendAsync(request); - response.EnsureSuccessStatusCode(); + var legalType = "A,B,BC,BEN,C,CC,CCC,CEM,CP,CS,CUL,EPR,FI,FOR,GP,LIC,LIB,LL,LLC,LP,MF,PA,PAR,PFS,QA,QB,QC,QD,QE,REG,RLY,S,SB,SP,T,TMY,ULC,UQA,UQB,UQC,UQD,UQE,XCP,XL,XP,XS"; + var status = "active"; + var queryString = $"?query=value:{queryValue}::identifier:::bn:::name:" + + $"&categories=legalType:{legalType}::status:{status}"; - BCRegistrySearchResult? searchResult = await response.Content.ReadFromJsonAsync(); + var path = $"{_BCRegistrySettings.RegistrySearchUrl}" + $"{queryString}"; - if (searchResult is null || searchResult.searchResults.totalResults < 1) - { - // Todo: Add a new message for this scenario or try seach by name - _logger.LogError(CustomLogEvent.Process, "No results found."); - return ProcessResult.PartialSuccess(ProcessId, ["No records found."], 0, 0).SimpleProcessResult; - } + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Get, path); + request.Headers.Add("Account-Id", "1"); + request.Headers.Add(_BCRegistrySettings.KeyName, _BCRegistrySettings.KeyValue); - if (searchResult.searchResults.totalResults > 1) - { - // ToDo: Process and filter the result further - _logger.LogError(CustomLogEvent.Process, "More than one records returned. Please resolve this issue to ensure uniqueness"); - return ProcessResult.PartialSuccess(ProcessId, ["Multiple results returned."], 0, 0).SimpleProcessResult; - } + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + + BCRegistrySearchResult? searchResult = await response.Content.ReadFromJsonAsync(); + + var responseBody = await response.Content.ReadAsStringAsync(); + + // Organization - Update + var goodStandingStatus = 3; // 1 - Good, 2 - No Good, 3 - Error + + // Integration Log - Create + var externalService = "BC Registries"; + var subject = string.Empty; + var logCategory = 1; // 1 - Info, 2 - Warning, 3 - Error, 4 - Critical + var message = $"{responseBody.CleanLog()}"; + + if (searchResult is null || searchResult.searchResults.totalResults < 1) + { + // Todo: Add a new message for this scenario or try seach by name + _logger.LogError(CustomLogEvent.Process, "No results found."); + + goodStandingStatus = 3; + logCategory = 3; + subject = "No results found"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.PartialSuccess(ProcessId, ["No records found."], 0, 0).SimpleProcessResult; + } + + if (searchResult.searchResults.totalResults > 1) + { + // ToDo: Process and filter the result further + _logger.LogError(CustomLogEvent.Process, "More than one records returned. Please resolve this issue to ensure uniqueness"); + + goodStandingStatus = 3; + logCategory = 3; + subject = "Multiple results returned"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.PartialSuccess(ProcessId, ["Multiple results returned."], 0, 0).SimpleProcessResult; + } + + if (searchResult.searchResults.totalResults == 1) + { + goodStandingStatus = searchResult.searchResults.results.First().goodStanding ? 1 : 2; // 1 - Good, 2 - No Good, 3 - Error + logCategory = 1; // 1 - Info, 2 - Warning, 3 - Error, 4 - Critical + subject = "One result found"; + await UpdateOrganizationCreateIntegrationLog(_appUserService, _d365webapiservice, organizationId, goodStandingStatus, subject, logCategory, message, externalService); + // return ProcessResult.Completed(ProcessId).SimpleProcessResult; + } - var statement = $"accounts({_processParams?.Organization?.organizationId.ToString()})"; + }); + return ProcessResult.Completed(ProcessId).SimpleProcessResult; + } + + private async Task UpdateOrganizationCreateIntegrationLog(ID365AppUserService appUserService, ID365WebApiService d365WebApiService, String organizationId, int goodStandingStatus, string subject, int category, string message, string externalService) + { + var statement = $"accounts({organizationId})"; var payload = new JsonObject { - { "ofm_good_standing_status", searchResult.searchResults.results.First().goodStanding ? 1 : 0}, + { "ofm_good_standing_status", goodStandingStatus}, { "ofm_good_standing_validated_on", DateTime.UtcNow } }; @@ -153,6 +210,17 @@ public async Task RunProcessAsync(ID365AppUserService appUserService return ProcessResult.Failure(ProcessId, new String[] { responseBody }, 0, 0).SimpleProcessResult; } + var entitySetName = "ofm_integration_logs"; + var payload2 = new JsonObject { + { "ofm_subject", subject }, + { "ofm_category", category}, + { "ofm_message", message}, + { "ofm_service_name", externalService}, + { "ofm_regardingid_account@odata.bind", $"/accounts({organizationId})"} + }; + var requestBody2 = JsonSerializer.Serialize(payload2); + var CreateResponse = await d365WebApiService.SendCreateRequestAsync(appUserService.AZSystemAppUser, entitySetName, requestBody2); + return ProcessResult.Completed(ProcessId).SimpleProcessResult; } } \ No newline at end of file