Skip to content

Commit

Permalink
PRIME-2529 Fill missing organization registration id (#2483)
Browse files Browse the repository at this point in the history
* initial commit

* fix PR issue

* more fix

* fix PR issues
  • Loading branch information
bergomi02 authored Jun 28, 2024
1 parent 0c1f2f5 commit dc620c8
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 3 deletions.
22 changes: 20 additions & 2 deletions prime-dotnet-webapi/Controllers/JobsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ namespace Prime.Controllers
public class JobsController : PrimeControllerBase
{
private readonly IReportingService _reportingService;
private readonly IOrganizationService _organizationService;

public JobsController(
IReportingService reportingService)
IReportingService reportingService,
IOrganizationService organizationService)
{
_reportingService = reportingService;
_organizationService = organizationService;
}

// POST: api/jobs/populate/practitioner
Expand Down Expand Up @@ -53,7 +57,6 @@ public async Task<ActionResult> UpdatePractitionerTable()
return Ok(result);
}


// POST: api/jobs/populate/transaction-log-temp
/// <summary>
/// copy transaction log to temp table for reporting.
Expand All @@ -77,5 +80,20 @@ public async Task<ActionResult> PopulateTransactionLogTemp(int numberOfDays)
var result = await _reportingService.PopulateTransactionLogTempAsync(numberOfDays);
return Ok(result);
}

// POST: api/jobs/populate/organization-registration-id
/// <summary>
/// execute job to update organization registration ID where the registration ID is missing, then return the number of organizations updated.
/// </summary>
[HttpPost("populate/organization-registration-id", Name = nameof(UpdateMissingRegistrationIds))]
[Authorize(Roles = Roles.PrimeApiServiceAccount)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> UpdateMissingRegistrationIds()
{
var result = await _organizationService.UpdateMissingRegistrationIds();
return Ok(result);
}
}
}
11 changes: 11 additions & 0 deletions prime-dotnet-webapi/HttpClients/Org Book API/IOrgBookClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;

using Prime.HttpClients.PharmanetCollegeApiDefinitions;

namespace Prime.HttpClients
{
public interface IOrgBookClient
{
Task<string> GetOrgBookRegistrationIdAsync(string orgName);
}
}
60 changes: 60 additions & 0 deletions prime-dotnet-webapi/HttpClients/Org Book API/OrgBookClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;

namespace Prime.HttpClients
{
public class OrgBookClient : BaseClient, IOrgBookClient
{
private readonly HttpClient _client;
private readonly ILogger _logger;

public OrgBookClient(HttpClient client,
ILogger<OrgBookClient> logger)
: base(PropertySerialization.CamelCase)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
_logger = logger;
}

public async Task<string> GetOrgBookRegistrationIdAsync(string orgName)
{
string registrationId = null;
HttpResponseMessage response = null;
try
{
response = await _client.GetAsync($"https://www.orgbook.gov.bc.ca/api/v2/search/credential/topic/facets?name=${HttpUtility.UrlEncode(orgName)}");
}
catch (Exception ex)
{
_logger.LogError($"Exception: {ex.Message} for orgName: {orgName}");
}

if (response != null)
{
string searchResult = await response.Content.ReadAsStringAsync();

try
{
var json = JObject.Parse(searchResult);

var objectResults = json["objects"]["results"].Where(r => r["topic"]["names"][0]["text"].ToString() == orgName);
if (objectResults.Count() > 0)
{
registrationId = objectResults.First()["topic"]["source_id"].ToString();
}
}
catch (Exception ex)
{
_logger.LogError($"Exception: {ex.Message} for orgName: {orgName}");
}
}

return registrationId;
}
}
}
30 changes: 29 additions & 1 deletion prime-dotnet-webapi/Services/OrganizationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class OrganizationService : BaseService, IOrganizationService
private readonly IMapper _mapper;
private readonly IOrganizationClaimService _organizationClaimService;
private readonly IPartyService _partyService;
private readonly IOrgBookClient _orgBookClient;

public OrganizationService(
ApiDbContext context,
Expand All @@ -30,14 +31,16 @@ public OrganizationService(
IDocumentManagerClient documentClient,
IMapper mapper,
IOrganizationClaimService organizationClaimService,
IPartyService partyService)
IPartyService partyService,
IOrgBookClient orgBookClient)
: base(context, logger)
{
_businessEventService = businessEventService;
_documentClient = documentClient;
_mapper = mapper;
_organizationClaimService = organizationClaimService;
_partyService = partyService;
_orgBookClient = orgBookClient;
}

public async Task<bool> OrganizationExistsAsync(int organizationId)
Expand Down Expand Up @@ -381,5 +384,30 @@ public async Task RemoveUnsignedOrganizationAgreementsAsync(int organizationId)
_context.RemoveRange(pendingAgreements);
await _context.SaveChangesAsync();
}

// update organization registration ID calling OrgBook API with organization name in PRIME, then return the number of organizations updated
public async Task<int> UpdateMissingRegistrationIds()
{
var targetOrganizations = await _context.Organizations.Where(o => o.RegistrationId == null)
.OrderBy(o => o.Id)
.ToListAsync();
int numUpdated = 0;
if (targetOrganizations.Any())
{
foreach (var org in targetOrganizations)
{
string registrationId = await _orgBookClient.GetOrgBookRegistrationIdAsync(org.Name);
if (registrationId != null)
{
org.RegistrationId = registrationId;
numUpdated++;
_logger.LogInformation($"Organization (ID:{org.Id}) registration ID is set to {registrationId}.");
}
}
await _context.SaveChangesAsync();
}

return numUpdated;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ public interface IOrganizationService
Task RemoveUnsignedOrganizationAgreementsAsync(int organizationId);
Task<bool> IsOrganizationTransferCompleteAsync(int organizationId);
Task FlagPendingTransferIfOrganizationAgreementsRequireSignaturesAsync(int organizationId);
Task<int> UpdateMissingRegistrationIds();
}
}
2 changes: 2 additions & 0 deletions prime-dotnet-webapi/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ private void ConfigureClients(IServiceCollection services)
client.BaseAddress = new Uri(PrimeConfiguration.Current.VerifiableCredentialApi.Url.EnsureTrailingSlash());
client.DefaultRequestHeaders.Add("x-api-key", PrimeConfiguration.Current.VerifiableCredentialApi.Key);
});

services.AddHttpClient<IOrgBookClient, OrgBookClient>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down

0 comments on commit dc620c8

Please sign in to comment.