Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BAH-3773 | Add. link patient abha identifier after successful linking #167

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/In.ProjectEKA.HipService/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static class Constants
public static readonly string PATH_OPENMRS_HITYPE = "ws/rest/v1/hip/";
public static readonly string CONFIG_KEY = "OpenMrs";
public static readonly string PATH_OPENMRS_LGD_CODE = "ws/rest/v1/hip/lgdCode";
public static readonly string PATH_OPENMRS_UPDATE_IDENTIFIER = "ws/rest/v1/hip/existingPatients/update";

public const string CORRELATION_ID = "CORRELATION-ID";
public const string PATH_PATIENT_PROFILE_ON_SHARE = "/" + CURRENT_VERSION + "/patients/profile/on-share";
Expand Down
9 changes: 9 additions & 0 deletions src/In.ProjectEKA.HipService/Discovery/DiscoveryReqMap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using In.ProjectEKA.HipLibrary.Patient.Model;

namespace In.ProjectEKA.HipService.Discovery
{
public static class DiscoveryReqMap {
public static Dictionary<string, PatientEnquiry> PatientInfoMap = new Dictionary<string, PatientEnquiry>();
}
}
10 changes: 9 additions & 1 deletion src/In.ProjectEKA.HipService/Discovery/PatientController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace In.ProjectEKA.HipService.Discovery
using System.Linq;

namespace In.ProjectEKA.HipService.Discovery
{
using System;
using System.Net;
Expand All @@ -12,6 +14,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using static In.ProjectEKA.HipService.Discovery.DiscoveryReqMap;
using Common;


Expand Down Expand Up @@ -71,6 +74,11 @@ public async Task GetPatientCareContext(DiscoveryRequest request, string correla
new DiscoveryResponse(request.RequestId,
error == null ? HttpStatusCode.OK : HttpStatusCode.NotFound,
error == null ? SuccessMessage : ErrorMessage));
if (!PatientInfoMap.ContainsKey(patientId))
{
PatientInfoMap.Add(patientId, request.Patient);
}

Log.Information("new GatewayDiscoveryRepresentation" + gatewayDiscoveryRepresentation);
Log.Information("Sending data to gateway");
Log.Information($"Response about to be send for {request.RequestId} with {@response?.Patient}");
Expand Down
56 changes: 51 additions & 5 deletions src/In.ProjectEKA.HipService/Link/LinkPatient.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
using In.ProjectEKA.HipService.OpenMrs;
using In.ProjectEKA.HipService.UserAuth;
using In.ProjectEKA.HipService.UserAuth.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace In.ProjectEKA.HipService.Link
{
using System;
Expand All @@ -11,7 +17,8 @@ namespace In.ProjectEKA.HipService.Link
using Logger;
using Microsoft.Extensions.Options;
using Model;

using static In.ProjectEKA.HipService.Discovery.DiscoveryReqMap;

public class LinkPatient
{
private readonly IDiscoveryRequestRepository discoveryRequestRepository;
Expand All @@ -20,21 +27,26 @@ public class LinkPatient
private readonly IPatientRepository patientRepository;
private readonly IPatientVerification patientVerification;
private readonly ReferenceNumberGenerator referenceNumberGenerator;
private readonly IOpenMrsClient openMrsClient;
private readonly IUserAuthService userAuthService;

public LinkPatient(
ILinkPatientRepository linkPatientRepository,
IPatientRepository patientRepository,
IPatientVerification patientVerification,
ReferenceNumberGenerator referenceNumberGenerator,
IDiscoveryRequestRepository discoveryRequestRepository,
IOptions<OtpServiceConfiguration> otpService)
IOptions<OtpServiceConfiguration> otpService,
IOpenMrsClient openMrsClient, IUserAuthService userAuthService)
{
this.linkPatientRepository = linkPatientRepository;
this.patientRepository = patientRepository;
this.patientVerification = patientVerification;
this.referenceNumberGenerator = referenceNumberGenerator;
this.discoveryRequestRepository = discoveryRequestRepository;
this.otpService = otpService;
this.openMrsClient = openMrsClient;
this.userAuthService = userAuthService;
}

public virtual async Task<ValueTuple<PatientLinkEnquiryRepresentation, ErrorRepresentation>> LinkPatients(
Expand Down Expand Up @@ -157,9 +169,13 @@ public virtual async Task<ValueTuple<PatientLinkConfirmationRepresentation, stri
linkEnquires.PatientReferenceNumber,
$"{patient.Name}",
representations));
return await SaveLinkedAccounts(linkEnquires,patient.Uuid)
? (patientLinkResponse,cmId, (ErrorRepresentation) null)
: (null,cmId,
var resp = await SaveLinkedAccounts(linkEnquires, patient.Uuid);
if (resp)
{
LinkAbhaIdentifier(patient.Uuid, linkEnquires.ConsentManagerUserId);
return (patientLinkResponse, cmId, (ErrorRepresentation) null);
}
return (null,cmId,
new ErrorRepresentation(new Error(ErrorCode.NoPatientFound,
ErrorMessage.NoPatientFound)));
}).ValueOr(
Expand All @@ -178,7 +194,37 @@ private async Task<bool> SaveLinkedAccounts(LinkEnquires linkEnquires,string pat
(patientUuid!=null?Guid.Parse(patientUuid): Guid.Empty)
)
.ConfigureAwait(false);

return linkedAccount.HasValue;

}

private async void LinkAbhaIdentifier(string patientUuid, string abhaAddress)
{
var patient = PatientInfoMap[abhaAddress];
var abhaNumberIdentifier = patient?.VerifiedIdentifiers.FirstOrDefault(id => id.Type == IdentifierType.NDHM_HEALTH_NUMBER);
var json = JsonConvert.SerializeObject(new PatientAbhaIdentifier(abhaNumberIdentifier?.Value, abhaAddress), new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
});
var resp = await openMrsClient.PostAsync(
$"{Constants.PATH_OPENMRS_UPDATE_IDENTIFIER}/{patientUuid}",
json
)
.ConfigureAwait(false);
if (resp.IsSuccessStatusCode)
{
var ndhmDemographics = new NdhmDemographics(abhaAddress, patient.Name, patient.Gender.ToString(), patient.YearOfBirth.ToString(), patient.VerifiedIdentifiers.FirstOrDefault(id => id.Type == IdentifierType.MOBILE)?.Value);
await userAuthService.Dump(ndhmDemographics);
}
else
{
Log.Error("Errored in linking the abha identifier to the patient");
}
}

public async Task<bool> SaveInitiatedLinkRequest(string requestId, string transactionId,
Expand Down
14 changes: 14 additions & 0 deletions src/In.ProjectEKA.HipService/Link/Model/PatientAbhaIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace In.ProjectEKA.HipService.Link.Model
{
public class PatientAbhaIdentifier
{
public string abhaNumber { get; }
public string abhaAddress { get; }

public PatientAbhaIdentifier(string abhaNumber, string abhaAddress)
{
this.abhaNumber = abhaNumber;
this.abhaAddress = abhaAddress;
}
}
}
2 changes: 2 additions & 0 deletions src/In.ProjectEKA.HipService/OpenMrs/IOpenMrsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ namespace In.ProjectEKA.HipService.OpenMrs
public interface IOpenMrsClient
{
Task<HttpResponseMessage> GetAsync(string openMrsUrl);

Task<HttpResponseMessage> PostAsync(string openMrsUrl, string jsonContent);
}
}
18 changes: 18 additions & 0 deletions src/In.ProjectEKA.HipService/OpenMrs/OpenMrsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ public async Task<HttpResponseMessage> GetAsync(string openMrsUrl)

return responseMessage;
}

public async Task<HttpResponseMessage> PostAsync(string openMrsUrl, string jsonContent)
{
var httpContent = new StringContent(jsonContent, Encoding.UTF8, "application/json");

var responseMessage = await httpClient.PostAsync(Path.Join(configuration.Url, openMrsUrl), httpContent);

if (!responseMessage.IsSuccessStatusCode)
{
var error = await responseMessage.Content.ReadAsStringAsync();
Log.Error(
$"Failure in posting the data into OpenMrs with status code {responseMessage.StatusCode}" +
$" {error}");
throw new OpenMrsConnectionException();
}

return responseMessage;
}

private void SettingUpHeaderAuthorization()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@
{
discoveryRequest = new DiscoveryRequestPayloadBuilder()
.FromUser(user)
.WithVerifiedIdentifiers(IdentifierType.NDHM_HEALTH_NUMBER, "12345678910")
.WithRequestId("aRequestId")
.WithTransactionId("aTransactionId")
.RequestedOn(new DateTime(2020, 06, 14))
Expand All @@ -398,7 +399,7 @@

patientDiscoveryMock
.Setup(patientDiscovery => patientDiscovery.PatientFor(It.IsAny<DiscoveryRequest>()))
.Returns(async () => (discovery, null));

Check warning on line 402 in test/In.ProjectEKA.HipServiceTest/Discovery/PatientControllerTest.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

discoveryRepresentation = discovery;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class LinkControllerTest

public LinkControllerTest()
{
link = new Mock<LinkPatient>(MockBehavior.Strict, null, null, null, null, null, null);
link = new Mock<LinkPatient>(MockBehavior.Strict, null, null, null, null, null, null, null, null);
discoveryRequestRepository = new Mock<IDiscoveryRequestRepository>();
var gatewayClient = new Mock<GatewayClient>(MockBehavior.Strict, null, null);

Expand Down
27 changes: 26 additions & 1 deletion test/In.ProjectEKA.HipServiceTest/Link/LinkPatientTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
using System.Net;
using System.Net.Http;
using In.ProjectEKA.HipService.OpenMrs;
using In.ProjectEKA.HipService.UserAuth;

namespace In.ProjectEKA.HipServiceTest.Link
{
using System;
Expand Down Expand Up @@ -44,6 +49,8 @@ public class LinkPatientTest
private readonly Mock<IPatientRepository> patientRepository = new Mock<IPatientRepository>();
private readonly Mock<IPatientVerification> patientVerification = new Mock<IPatientVerification>();
private readonly Mock<ReferenceNumberGenerator> guidGenerator = new Mock<ReferenceNumberGenerator>();
private readonly Mock<IOpenMrsClient> openmrsClient = new Mock<IOpenMrsClient>();
private readonly Mock<IUserAuthService> userAuthService = new Mock<IUserAuthService>();

public LinkPatientTest()
{
Expand All @@ -54,7 +61,9 @@ public LinkPatientTest()
patientVerification.Object,
guidGenerator.Object,
discoveryRequestRepository.Object,
otpServiceConfigurations);
otpServiceConfigurations,
openmrsClient.Object,
userAuthService.Object);
}

[Fact]
Expand Down Expand Up @@ -211,6 +220,15 @@ private async void SuccessLinkPatientForValidOtp()
var testLinkedAccounts = new LinkedAccounts(testLinkRequest.PatientReferenceNumber,
testLinkRequest.LinkReferenceNumber,
testLinkRequest.ConsentManagerUserId, It.IsAny<string>(), new[] {programRefNo}.ToList(),It.IsAny<Guid>());
var patientEnquiry =
new PatientEnquiry(
"id", verifiedIdentifiers: new List<Identifier>()
{
new Identifier(IdentifierType.MOBILE, "9999999999"),
new Identifier(IdentifierType.NDHM_HEALTH_NUMBER, "123456718910")
}, unverifiedIdentifiers: null,
"name", HipLibrary.Patient.Model.Gender.M, 2000);
DiscoveryReqMap.PatientInfoMap.Add(testLinkRequest.ConsentManagerUserId, patientEnquiry);
patientVerification.Setup(e => e.Verify(sessionId, otpToken))
.ReturnsAsync((OtpMessage) null);
linkRepository.Setup(e => e.GetPatientFor(sessionId))
Expand All @@ -224,6 +242,13 @@ private async void SuccessLinkPatientForValidOtp()
It.IsAny<Guid>()
))
.ReturnsAsync(Option.Some(testLinkedAccounts));
openmrsClient
.Setup(x => x.PostAsync(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK
})
.Verifiable();
var expectedLinkResponse = new PatientLinkConfirmationRepresentation(
new LinkConfirmationRepresentation(
testPatient.Identifier,
Expand Down
Loading