Пример #1
0
        public async Task LinkPatient(LinkReferenceRequest request)
        {
            var cmUserId = request.Patient.Id;
            var cmSuffix = cmUserId.Substring(
                cmUserId.LastIndexOf("@", StringComparison.Ordinal) + 1);
            var patient = new LinkEnquiry(
                cmSuffix,
                cmUserId,
                request.Patient.ReferenceNumber,
                request.Patient.CareContexts);

            try
            {
                var doesRequestExists = await discoveryRequestRepository.RequestExistsFor(
                    request.TransactionId,
                    request.Patient?.Id,
                    request.Patient?.ReferenceNumber);

                ErrorRepresentation errorRepresentation = null;
                if (!doesRequestExists)
                {
                    errorRepresentation = new ErrorRepresentation(
                        new Error(ErrorCode.DiscoveryRequestNotFound, ErrorMessage.DiscoveryRequestNotFound));
                }

                var patientReferenceRequest =
                    new PatientLinkEnquiry(request.TransactionId, request.RequestId, patient);
                var patientLinkEnquiryRepresentation = new PatientLinkEnquiryRepresentation();

                var(linkReferenceResponse, error) = errorRepresentation != null
                    ? (patientLinkEnquiryRepresentation, errorRepresentation)
                    : await linkPatient.LinkPatients(patientReferenceRequest);

                var linkedPatientRepresentation = new LinkEnquiryRepresentation();
                if (linkReferenceResponse != null)
                {
                    linkedPatientRepresentation = linkReferenceResponse.Link;
                }
                var response = new GatewayLinkResponse(
                    linkedPatientRepresentation,
                    error?.Error,
                    new Resp(request.RequestId),
                    request.TransactionId,
                    DateTime.Now.ToUniversalTime(),
                    Guid.NewGuid());

                await gatewayClient.SendDataToGateway(PATH_ON_LINK_INIT, response, cmSuffix);
            }
            catch (Exception exception)
            {
                Log.Error(exception, exception.StackTrace);
            }
        }
Пример #2
0
        private async void ShouldReturnLinkReferenceResponse()
        {
            const string linkReferenceNumber = "linkreference";
            const string authType            = "MEDIATED";
            const string programRefNo        = "129";
            const string medium = "MOBILE";

            IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry(programRefNo) };
            var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                          TestBuilders.Faker().Random.Hash(), testPatient.Identifier, careContexts);
            var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                                                 TestBuilders.Faker().Random.Hash(), patient);

            guidGenerator.Setup(x => x.NewGuid()).Returns(linkReferenceNumber);
            patientVerification.Setup(x => x.SendTokenFor(new Session(linkReferenceNumber
                                                                      , new Communication(CommunicationMode.MOBILE, testPatient.PhoneNumber)
                                                                      , new OtpGenerationDetail(TestBuilder.Faker().Random.Word(), OtpAction.LINK_PATIENT_CARECONTEXT.ToString()))))
            .ReturnsAsync((OtpMessage)null);
            var initiatedLinkRequest = new InitiatedLinkRequest(patientReferenceRequest.RequestId,
                                                                patientReferenceRequest.TransactionId,
                                                                linkReferenceNumber,
                                                                false,
                                                                It.IsAny <string>());

            linkRepository.Setup(x => x.SaveRequestWith(linkReferenceNumber,
                                                        patientReferenceRequest.Patient.ConsentManagerId,
                                                        patientReferenceRequest.Patient.ConsentManagerUserId,
                                                        patientReferenceRequest.Patient.ReferenceNumber, new[] { programRefNo }))
            .ReturnsAsync(new Tuple <LinkEnquires, Exception>(null, null));
            linkRepository.Setup(x => x.Save(patientReferenceRequest.RequestId,
                                             patientReferenceRequest.TransactionId,
                                             linkReferenceNumber))
            .ReturnsAsync(Option.Some(initiatedLinkRequest));

            patientRepository.Setup(x => x.PatientWith(testPatient.Identifier))
            .Returns(Option.Some(testPatient));

            var(response, _) = await linkPatient.LinkPatients(patientReferenceRequest);

            patientVerification.Verify();
            linkRepository.Verify();
            guidGenerator.Verify();
            discoveryRequestRepository.Verify(x => x.Delete(patientReferenceRequest.TransactionId,
                                                            patientReferenceRequest.Patient.ConsentManagerUserId));
            response.Link.ReferenceNumber.Should().Be(linkReferenceNumber);
            response.Link.AuthenticationType.Should().Be(authType);
            response.Link.Meta.CommunicationHint.Should().Be(testPatient.PhoneNumber);
            response.Link.Meta.CommunicationMedium.Should().Be(medium);
            response.Link.Should().NotBeNull();
        }
Пример #3
0
        private async void ShouldReturnPatientNotFoundError()
        {
            IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry("129") };
            var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                          TestBuilders.Faker().Random.Hash(), "1234", careContexts);
            var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                                                 TestBuilders.Faker().Random.Hash(), patient);
            var expectedError =
                new ErrorRepresentation(new Error(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound));

            var(_, error) = await linkPatient.LinkPatients(patientReferenceRequest);

            error.Should().BeEquivalentTo(expectedError);
        }
Пример #4
0
        private async void ShouldReturnCareContextNotFoundError()
        {
            IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry("1234") };
            var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                          TestBuilders.Faker().Random.Hash(), "4", careContexts);
            var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                                                 TestBuilders.Faker().Random.Hash(), patient);

            patientRepository.Setup(e => e.PatientWith(testPatient.Identifier))
            .Returns(Option.Some(testPatient));
            var expectedError = new ErrorRepresentation(
                new Error(ErrorCode.CareContextNotFound, ErrorMessage.CareContextNotFound));

            var(_, error) = await linkPatient.LinkPatients(patientReferenceRequest);

            patientRepository.Verify();
            discoveryRequestRepository.Invocations.Count.Should().Be(0);
            error.Should().BeEquivalentTo(expectedError);
        }
Пример #5
0
        private async Task <ValueTuple <Patient, ErrorRepresentation> > PatientAndCareContextValidation(
            PatientLinkEnquiry request)
        {
            var patient = await patientRepository.PatientWithAsync(request.Patient.ReferenceNumber);

            return(patient.Map(patient =>
            {
                var programs = request.Patient.CareContexts
                               .Where(careContext =>
                                      patient.CareContexts.Any(c => c.ReferenceNumber == careContext.ReferenceNumber))
                               .Select(context => new CareContextRepresentation(context.ReferenceNumber,
                                                                                patient.CareContexts.First(info => info.ReferenceNumber == context.ReferenceNumber)
                                                                                .Display)).ToList();
                if (programs.Count != request.Patient.CareContexts.Count())
                {
                    return (null, new ErrorRepresentation(new Error(ErrorCode.CareContextNotFound,
                                                                    ErrorMessage.CareContextNotFound)));
                }

                return (patient, (ErrorRepresentation)null);
            })
                   .ValueOr((null,
                             new ErrorRepresentation(new Error(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound)))));
        }
Пример #6
0
        private async void ErrorOnDuplicateRequestId()
        {
            const string linkReferenceNumber   = "linkreference";
            const string programRefNo          = "129";
            var          expectedErrorResponse =
                new ErrorRepresentation(new Error(ErrorCode.DuplicateRequestId, ErrorMessage.DuplicateRequestId));
            IEnumerable <CareContextEnquiry> careContexts = new[] { new CareContextEnquiry(programRefNo) };
            var patient = new LinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                          TestBuilders.Faker().Random.Hash(), testPatient.Identifier, careContexts);
            var patientReferenceRequest = new PatientLinkEnquiry(TestBuilders.Faker().Random.Hash(),
                                                                 TestBuilders.Faker().Random.Hash(), patient);

            guidGenerator.Setup(x => x.NewGuid()).Returns(linkReferenceNumber);
            patientVerification.Setup(x => x.SendTokenFor(new Session(linkReferenceNumber
                                                                      , new Communication(CommunicationMode.MOBILE, testPatient.PhoneNumber),
                                                                      new OtpGenerationDetail(TestBuilder.Faker().Random.Word(), OtpAction.LINK_PATIENT_CARECONTEXT.ToString()))))
            .ReturnsAsync((OtpMessage)null);
            linkRepository.Setup(x => x.SaveRequestWith(linkReferenceNumber,
                                                        patientReferenceRequest.Patient.ConsentManagerId,
                                                        patientReferenceRequest.Patient.ConsentManagerUserId,
                                                        patientReferenceRequest.Patient.ReferenceNumber, new[] { programRefNo }))
            .ReturnsAsync(new Tuple <LinkEnquires, Exception>(null, null));
            linkRepository.Setup(x => x.Save(patientReferenceRequest.RequestId,
                                             patientReferenceRequest.TransactionId,
                                             linkReferenceNumber))
            .ReturnsAsync(Option.None <InitiatedLinkRequest>());
            patientRepository.Setup(x => x.PatientWith(testPatient.Identifier))
            .Returns(Option.Some(testPatient));
            var(_, errorRepresentation) = await linkPatient.LinkPatients(patientReferenceRequest);

            patientVerification.Verify();
            linkRepository.Verify();
            guidGenerator.Verify();

            errorRepresentation.Should().BeEquivalentTo(expectedErrorResponse);
        }
Пример #7
0
        public virtual async Task <ValueTuple <PatientLinkEnquiryRepresentation, ErrorRepresentation> > LinkPatients(
            PatientLinkEnquiry request)
        {
            var(patient, error) = await PatientAndCareContextValidation(request);

            if (error != null)
            {
                Log.Error(error.Error.Message);
                return(null, error);
            }

            var linkRefNumber = referenceNumberGenerator.NewGuid();

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                if (!await SaveInitiatedLinkRequest(request.RequestId, request.TransactionId, linkRefNumber)
                    .ConfigureAwait(false))
                {
                    return(null,
                           new ErrorRepresentation(new Error(ErrorCode.DuplicateRequestId, ErrorMessage.DuplicateRequestId))
                           );
                }

                var careContextReferenceNumbers = request.Patient.CareContexts
                                                  .Select(context => context.ReferenceNumber)
                                                  .ToArray();
                var(_, exception) = await linkPatientRepository.SaveRequestWith(
                    linkRefNumber,
                    request.Patient.ConsentManagerId,
                    request.Patient.ConsentManagerUserId,
                    request.Patient.ReferenceNumber,
                    careContextReferenceNumbers)
                                    .ConfigureAwait(false);

                if (exception != null)
                {
                    return(null,
                           new ErrorRepresentation(new Error(ErrorCode.ServerInternalError,
                                                             ErrorMessage.DatabaseStorageError)));
                }

                var session = new Session(
                    linkRefNumber,
                    new Communication(CommunicationMode.MOBILE, patient.PhoneNumber),
                    new OtpGenerationDetail(otpService.Value.SenderSystemName,
                                            OtpAction.LINK_PATIENT_CARECONTEXT.ToString()));
                var otpGeneration = await patientVerification.SendTokenFor(session);

                if (otpGeneration != null)
                {
                    return(null,
                           new ErrorRepresentation(new Error(ErrorCode.OtpGenerationFailed, otpGeneration.Message)));
                }

                await discoveryRequestRepository.Delete(request.TransactionId, request.Patient.ConsentManagerUserId)
                .ConfigureAwait(false);

                scope.Complete();
            }

            var time   = new TimeSpan(0, 0, otpService.Value.OffsetInMinutes, 0);
            var expiry = DateTime.Now.Add(time).ToUniversalTime().ToString(Constants.DateTimeFormat);
            var meta   = new LinkReferenceMeta(nameof(CommunicationMode.MOBILE), patient.PhoneNumber, expiry);
            var patientLinkReferenceResponse = new PatientLinkEnquiryRepresentation(
                new LinkEnquiryRepresentation(linkRefNumber, "MEDIATED", meta));

            return(patientLinkReferenceResponse, null);
        }