Example #1
0
        public virtual async Task <ValueTuple <DiscoveryRepresentation, ErrorRepresentation> > PatientFor(
            DiscoveryRequest request)
        {
            if (await AlreadyExists(request.TransactionId))
            {
                logger.Log(LogLevel.Error, LogEvents.Discovery, "Discovery Request already exists");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.DuplicateDiscoveryRequest,
                                                         "Discovery Request already exists")));
            }

            var(linkedAccounts, exception) = await linkPatientRepository.GetLinkedCareContexts(request.Patient.Id);

            if (exception != null)
            {
                logger.Log(LogLevel.Critical, LogEvents.Discovery, exception, "Failed to get care contexts");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.FailedToGetLinkedCareContexts,
                                                         "Failed to get Linked Care Contexts")));
            }

            var linkedCareContexts = linkedAccounts.ToList();

            if (HasAny(linkedCareContexts))
            {
                logger.Log(LogLevel.Information,
                           LogEvents.Discovery,
                           "User has already linked care contexts: {TransactionID}",
                           request.TransactionId);
                return(await patientRepository.PatientWith(linkedCareContexts.First().PatientReferenceNumber)
                       .Map(async patient =>
                {
                    await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                                    request.Patient.Id,
                                                                                    patient.Identifier));
                    return (new DiscoveryRepresentation(patient.ToPatientEnquiryRepresentation(
                                                            GetUnlinkedCareContexts(linkedCareContexts, patient))),
                            (ErrorRepresentation)null);
                })
                       .ValueOr(Task.FromResult(((DiscoveryRepresentation)null,
                                                 new ErrorRepresentation(new Error(ErrorCode.NoPatientFound,
                                                                                   ErrorMessage.NoPatientFound))))));
            }

            var patients = await matchingRepository.Where(request);

            var(patientEnquiryRepresentation, error) =
                DiscoveryUseCase.DiscoverPatient(Filter.Do(patients, request).AsQueryable());
            if (patientEnquiryRepresentation == null)
            {
                logger.Log(LogLevel.Error,
                           LogEvents.Discovery,
                           "Error {@Error} for: {TransactionID}",
                           error,
                           request.TransactionId);
                return(null, error);
            }

            await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                            request.Patient.Id, patientEnquiryRepresentation.ReferenceNumber));

            return(new DiscoveryRepresentation(patientEnquiryRepresentation), null);
        }
        public virtual async Task <ValueTuple <DiscoveryRepresentation, ErrorRepresentation> > PatientFor(
            DiscoveryRequest request)
        {
            if (await AlreadyExists(request.TransactionId))
            {
                logger.Log(LogLevel.Error, LogEvents.Discovery, "Discovery Request already exists for {request.TransactionId}.");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.DuplicateDiscoveryRequest, "Discovery Request already exists")));
            }

            var(linkedAccounts, exception) = await linkPatientRepository.GetLinkedCareContexts(request.Patient.Id);

            if (exception != null)
            {
                logger.Log(LogLevel.Critical, LogEvents.Discovery, exception, "Failed to get care contexts");
                return(null,
                       new ErrorRepresentation(new Error(ErrorCode.FailedToGetLinkedCareContexts,
                                                         "Failed to get Linked Care Contexts")));
            }

            var linkedCareContexts = linkedAccounts.ToList();

            if (HasAny(linkedCareContexts))
            {
                logger.Log(LogLevel.Information,
                           LogEvents.Discovery,
                           "User has already linked care contexts: {TransactionID}",
                           request.TransactionId);
                var patient = await patientRepository.PatientWithAsync(linkedCareContexts.First().PatientReferenceNumber);

                return(await patient
                       .Map(async patient =>
                {
                    await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                                    request.Patient.Id, patient.Identifier));
                    return (new DiscoveryRepresentation(patient.ToPatientEnquiryRepresentation(
                                                            GetUnlinkedCareContexts(linkedCareContexts, patient))),
                            (ErrorRepresentation)null);
                })
                       .ValueOr(Task.FromResult(GetError(ErrorCode.NoPatientFound, ErrorMessage.NoPatientFound))));
            }
            IQueryable <Patient> patients;

            try {
                patients = await matchingRepository.Where(request);
            }
            catch (OpenMrsConnectionException)
            {
                return(GetError(ErrorCode.OpenMrsConnection, ErrorMessage.HipConnection));
            }

            try
            {
                foreach (var patient in patients)
                {
                    var careContexts = await careContextRepository.GetCareContexts(patient.Uuid);

                    patient.CareContexts = careContexts;
                }
            }
            catch (OpenMrsFormatException e)
            {
                logger.Log(LogLevel.Error,
                           LogEvents.Discovery, $"Could not get care contexts for transaction {request.TransactionId}.", e);
                return(GetError(ErrorCode.CareContextConfiguration, ErrorMessage.HipConfiguration));
            }

            var(patientEnquiryRepresentation, error) =
                DiscoveryUseCase.DiscoverPatient(Filter.Do(patients, request).AsQueryable());
            if (patientEnquiryRepresentation == null)
            {
                Log.Information($"No matching unique patient found for transaction {request.TransactionId}.", error);
                return(null, error);
            }

            await discoveryRequestRepository.Add(new Model.DiscoveryRequest(request.TransactionId,
                                                                            request.Patient.Id, patientEnquiryRepresentation.ReferenceNumber));

            return(new DiscoveryRepresentation(patientEnquiryRepresentation), null);
        }