Beispiel #1
0
        /// <inheritdoc />
        public PrimitiveRequestResult <bool> ValidateEmail(string hdid, Guid inviteKey)
        {
            this.logger.LogTrace($"Validating email... {inviteKey}");
            PrimitiveRequestResult <bool> retVal = new ();

            MessagingVerification?emailVerification = this.messageVerificationDelegate.GetLastByInviteKey(inviteKey);

            if (emailVerification == null ||
                emailVerification.HdId != hdid ||
                emailVerification.Validated == true ||
                emailVerification.Deleted == true)
            {
                // Invalid Verification Attempt
                emailVerification = this.messageVerificationDelegate.GetLastForUser(hdid, MessagingVerificationType.Email);
                if (emailVerification != null &&
                    !emailVerification.Validated)
                {
                    emailVerification.VerificationAttempts++;
                    this.messageVerificationDelegate.Update(emailVerification);
                }

                return(new PrimitiveRequestResult <bool>()
                {
                    ResultStatus = ResultType.Error,
                    ResultError = new RequestResultError()
                    {
                        ResultMessage = "Invalid Email Verification",
                        ErrorCode = ErrorTranslator.InternalError(ErrorType.InvalidState),
                    },
                });
            }
            else if (emailVerification.VerificationAttempts >= this.maxVerificationAttempts ||
                     emailVerification.ExpireDate < DateTime.UtcNow)
            {
                // Verification Expired
                retVal.ResultStatus = ResultType.ActionRequired;
                retVal.ResultError  = ErrorTranslator.ActionRequired("Email Verification Expired", ActionType.Expired);
            }
            else
            {
                emailVerification.Validated = true;
                this.messageVerificationDelegate.Update(emailVerification);
                UserProfile userProfile = this.profileDelegate.GetUserProfile(hdid).Payload;
                userProfile.Email = emailVerification.Email !.To; // Gets the user email from the email sent.
                this.profileDelegate.Update(userProfile);

                // Update the notification settings
                this.notificationSettingsService.QueueNotificationSettings(new NotificationSettingsRequest(userProfile, userProfile.Email, userProfile.SMSNumber));

                retVal.ResultStatus = ResultType.Success;
            }

            this.logger.LogDebug($"Finished validating email: {JsonConvert.SerializeObject(retVal)}");
            return(retVal);
        }
        public void ValidateDependentWithWrongDateOfBirth()
        {
            AddDependentRequest addDependentRequest = SetupMockInput();

            addDependentRequest.DateOfBirth = DateTime.Now;
            IDependentService service = SetupMockDependentService(addDependentRequest);
            RequestResult <DependentModel> actualResult = service.AddDependent(mockParentHdId, addDependentRequest);

            var userError = ErrorTranslator.ActionRequired(ErrorMessages.DataMismatch, ActionType.DataMismatch);

            Assert.Equal(Common.Constants.ResultType.ActionRequired, actualResult.ResultStatus);
            Assert.Equal(userError.ErrorCode, actualResult.ResultError.ErrorCode);
            Assert.Equal(mismatchedError, actualResult.ResultError.ResultMessage);
        }
        public void ValidateDependentWithNoHdId()
        {
            RequestResult <PatientModel> patientResult = new RequestResult <PatientModel>();

            patientResult.ResultStatus    = Common.Constants.ResultType.Success;
            patientResult.ResourcePayload = new PatientModel()
            {
                HdId = string.Empty,
                PersonalHealthNumber = mockPHN,
                FirstName            = mockFirstName,
                LastName             = mockLastName,
                Birthdate            = mockDateOfBirth,
                Gender = mockGender,
            };
            AddDependentRequest            addDependentRequest = SetupMockInput();
            IDependentService              service             = SetupMockDependentService(addDependentRequest, patientResult: patientResult);
            RequestResult <DependentModel> actualResult        = service.AddDependent(mockParentHdId, addDependentRequest);

            var userError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId);

            Assert.Equal(Common.Constants.ResultType.ActionRequired, actualResult.ResultStatus);
            Assert.Equal(userError.ErrorCode, actualResult.ResultError.ErrorCode);
            Assert.Equal(noHdIdError, actualResult.ResultError.ResultMessage);
        }
        private RequestResult <PatientModel> ParseResponse(HCIM_IN_GetDemographicsResponse1 reply)
        {
            using (Source.StartActivity("ParsePatientResponse"))
            {
                this.logger.LogDebug($"Parsing patient response... {JsonSerializer.Serialize(reply)}");

                // Verify that the reply contains a result
                string responseCode = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.queryAck.queryResponseCode.code;
                if (!responseCode.Contains("BCHCIM.GD.0.0013", StringComparison.InvariantCulture))
                {
                    PatientModel emptyPatient = new PatientModel();
                    this.logger.LogWarning($"Client Registry did not return a person. Returned message code: {responseCode}");
                    this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(emptyPatient)}");
                    return(new RequestResult <PatientModel>()
                    {
                        ResultStatus = ResultType.Error,
                        ResultError = new RequestResultError()
                        {
                            ResultMessage = "Client Registry did not return a person", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries)
                        },
                    });
                }

                HCIM_IN_GetDemographicsResponseIdentifiedPerson retrievedPerson = reply.HCIM_IN_GetDemographicsResponse.controlActProcess.subject[0].target;

                // If the deceased indicator is set and true, return an empty person.
                bool deceasedInd = retrievedPerson.identifiedPerson.deceasedInd?.value ?? false;
                if (deceasedInd)
                {
                    PatientModel emptyPatient = new PatientModel();
                    this.logger.LogWarning($"Client Registry returned a person with the deceasedIndicator set to true. No PHN was populated. {deceasedInd}");
                    this.logger.LogDebug($"Finished getting patient. {JsonSerializer.Serialize(emptyPatient)}");
                    return(new RequestResult <PatientModel>()
                    {
                        ResultStatus = ResultType.Error,
                        ResultError = new RequestResultError()
                        {
                            ResultMessage = "Client Registry returned a person with the deceasedIndicator set to true", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.ClientRegistries)
                        },
                    });
                }

                PN?nameSection = retrievedPerson.identifiedPerson.name.Where(x => x.use.Any(u => u == cs_EntityNameUse.C)).FirstOrDefault();

                if (nameSection == null)
                {
                    this.logger.LogWarning($"Client Registry returned a person with an invalid name.");
                    return(new RequestResult <PatientModel>()
                    {
                        ResultStatus = ResultType.ActionRequired,
                        ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.InvalidName),
                    });
                }

                // Extract the subject names
                List <string> givenNameList = new List <string>();
                List <string> lastNameList  = new List <string>();
                for (int i = 0; i < nameSection.Items.Length; i++)
                {
                    ENXP name = nameSection.Items[i];

                    if (name.GetType() == typeof(engiven) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL)))
                    {
                        givenNameList.Add(name.Text[0]);
                    }
                    else if (name.GetType() == typeof(enfamily) && (name.qualifier == null || !name.qualifier.Contains(cs_EntityNamePartQualifier.CL)))
                    {
                        lastNameList.Add(name.Text[0]);
                    }
                }

                string   delimiter  = " ";
                string   givenNames = givenNameList.Aggregate((i, j) => i + delimiter + j);
                string   lastNames  = lastNameList.Aggregate((i, j) => i + delimiter + j);
                string?  dobStr     = ((TS)retrievedPerson.identifiedPerson.birthTime).value; // yyyyMMdd
                DateTime dob        = DateTime.ParseExact(dobStr, "yyyyMMdd", CultureInfo.InvariantCulture);
                string   genderCode = retrievedPerson.identifiedPerson.administrativeGenderCode.code;
                string   gender     = "NotSpecified";
                if (genderCode == "F")
                {
                    gender = "Female";
                }
                else if (genderCode == "M")
                {
                    gender = "Male";
                }

                PatientModel patient = new PatientModel()
                {
                    FirstName = givenNames, LastName = lastNames, Birthdate = dob, Gender = gender, EmailAddress = string.Empty
                };

                II?    identifiedPersonId   = (II?)retrievedPerson.identifiedPerson.id.GetValue(0);
                string?personIdentifierType = identifiedPersonId?.root;
                string personIdentifier     = identifiedPersonId?.extension ?? string.Empty;
                if (personIdentifierType == OIDType.HDID.ToString())
                {
                    patient.HdId = personIdentifier;
                }
                else if (personIdentifierType == OIDType.PHN.ToString())
                {
                    patient.PersonalHealthNumber = personIdentifier;
                }
                else
                {
                    this.logger.LogWarning($"Client Registry returned a person with a person identifier not recognized. No PHN or HDID was populated.");
                    return(new RequestResult <PatientModel>()
                    {
                        ResultStatus = ResultType.ActionRequired,
                        ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId),
                    });
                }

                II?    subjectId             = (II?)retrievedPerson.id.GetValue(0);
                string?subjectIdentifierType = subjectId?.root;
                string subjectIdentifier     = subjectId?.extension ?? string.Empty;
                if (subjectIdentifierType == OIDType.HDID.ToString())
                {
                    patient.HdId = subjectIdentifier;
                }
                else if (personIdentifierType == OIDType.PHN.ToString())
                {
                    patient.PersonalHealthNumber = subjectIdentifier;
                }
                else
                {
                    this.logger.LogWarning($"Client Registry returned a person with a subject identifier not recognized. No PHN or HDID was populated.");
                    return(new RequestResult <PatientModel>()
                    {
                        ResultStatus = ResultType.ActionRequired,
                        ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId),
                    });
                }

                return(new RequestResult <PatientModel>()
                {
                    ResultStatus = ResultType.Success,
                    ResourcePayload = patient,
                });
            }
        }
Beispiel #5
0
        /// <inheritdoc/>
        public async Task <RequestResult <IList <MedicationStatementHistory> > > GetMedicationStatementsHistory(string hdid, string?protectiveWord)
        {
            using (Source.StartActivity("GetMedicationStatementsHistory"))
            {
                this.logger.LogDebug("Getting history of medication statements");
                this.logger.LogTrace($"User hdid: {hdid}");

                RequestResult <IList <MedicationStatementHistory> > result = new RequestResult <IList <MedicationStatementHistory> >();
                var  validationResult = ValidateProtectiveWord(protectiveWord);
                bool okProtectiveWord = validationResult.Item1;
                if (okProtectiveWord)
                {
                    // Retrieve the phn
                    RequestResult <PatientModel> patientResult = await this.patientService.GetPatient(hdid).ConfigureAwait(true);

                    if (patientResult.ResultStatus == ResultType.Success && patientResult.ResourcePayload != null)
                    {
                        PatientModel    patient      = patientResult.ResourcePayload;
                        ODRHistoryQuery historyQuery = new ODRHistoryQuery()
                        {
                            StartDate = patient.Birthdate,
                            EndDate   = System.DateTime.Now,
                            PHN       = patient.PersonalHealthNumber,
                            PageSize  = 20000,
                        };
                        IPAddress?address     = this.httpContextAccessor.HttpContext?.Connection.RemoteIpAddress;
                        string    ipv4Address = address?.MapToIPv4().ToString() ?? "Unknown";
                        RequestResult <MedicationHistoryResponse> response = await this.medicationStatementDelegate.GetMedicationStatementsAsync(historyQuery, protectiveWord, hdid, ipv4Address).ConfigureAwait(true);

                        result.ResultStatus = response.ResultStatus;
                        result.ResultError  = response.ResultError;
                        if (response.ResultStatus == ResultType.Success)
                        {
                            result.PageSize  = historyQuery.PageSize;
                            result.PageIndex = historyQuery.PageNumber;
                            if (response.ResourcePayload != null && response.ResourcePayload.Results != null)
                            {
                                result.TotalResultCount = response.ResourcePayload.TotalRecords;
                                result.ResourcePayload  = MedicationStatementHistory.FromODRModelList(response.ResourcePayload.Results.ToList());
                                this.PopulateMedicationSummary(result.ResourcePayload.Select(r => r.MedicationSummary).ToList());
                            }
                            else
                            {
                                result.ResourcePayload = new List <MedicationStatementHistory>();
                            }
                        }
                    }
                    else
                    {
                        result.ResultError = patientResult.ResultError;
                    }
                }
                else
                {
                    this.logger.LogInformation($"Invalid protective word. {hdid}");
                    result.ResultStatus = Common.Constants.ResultType.ActionRequired;
                    result.ResultError  = ErrorTranslator.ActionRequired(validationResult.Item2, ActionType.Protected);
                }

                this.logger.LogDebug($"Finished getting history of medication statements");
                return(result);
            }
        }
Beispiel #6
0
        /// <inheritdoc />
        public RequestResult <DependentModel> AddDependent(string delegateHdId, AddDependentRequest addDependentRequest)
        {
            this.logger.LogTrace($"Dependent hdid: {delegateHdId}");

            int?maxDependentAge = this.configurationService.GetConfiguration().WebClient.MaxDependentAge;

            if (maxDependentAge.HasValue)
            {
                DateTime minimumBirthDate = DateTime.UtcNow.AddYears(maxDependentAge.Value * -1);
                if (addDependentRequest.DateOfBirth < minimumBirthDate)
                {
                    return(new RequestResult <DependentModel>()
                    {
                        ResultStatus = ResultType.Error,
                        ResultError = new RequestResultError()
                        {
                            ResultMessage = "Dependent age exceeds the maximum limit", ErrorCode = ErrorTranslator.ServiceError(ErrorType.InvalidState, ServiceType.Patient)
                        },
                    });
                }
            }

            this.logger.LogTrace("Getting dependent details...");
            RequestResult <PatientModel> patientResult = Task.Run(async() => await this.patientService.GetPatient(addDependentRequest.PHN, PatientIdentifierType.PHN).ConfigureAwait(true)).Result;

            if (patientResult.ResultStatus == ResultType.Error)
            {
                return(new RequestResult <DependentModel>()
                {
                    ResultStatus = ResultType.Error,
                    ResultError = new RequestResultError()
                    {
                        ResultMessage = "Communication Exception when trying to retrieve the Dependent", ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationExternal, ServiceType.Patient)
                    },
                });
            }

            if (patientResult.ResultStatus == ResultType.ActionRequired)
            {
                return(new RequestResult <DependentModel>()
                {
                    ResultStatus = ResultType.ActionRequired,
                    ResultError = ErrorTranslator.ActionRequired(ErrorMessages.DataMismatch, ActionType.DataMismatch),
                });
            }

            this.logger.LogDebug($"Finished getting dependent details...{JsonSerializer.Serialize(patientResult)}");

            // Verify dependent's details entered by user
            if (patientResult.ResourcePayload == null || !this.ValidateDependent(addDependentRequest, patientResult.ResourcePayload))
            {
                this.logger.LogDebug($"Dependent information does not match request: {JsonSerializer.Serialize(addDependentRequest)} response: {JsonSerializer.Serialize(patientResult.ResourcePayload)}");
                return(new RequestResult <DependentModel>()
                {
                    ResultStatus = ResultType.ActionRequired,
                    ResultError = ErrorTranslator.ActionRequired(ErrorMessages.DataMismatch, ActionType.DataMismatch),
                });
            }

            // Verify dependent has HDID
            if (string.IsNullOrEmpty(patientResult.ResourcePayload.HdId))
            {
                return(new RequestResult <DependentModel>()
                {
                    ResultStatus = ResultType.ActionRequired,
                    ResultError = ErrorTranslator.ActionRequired(ErrorMessages.InvalidServicesCard, ActionType.NoHdId),
                });
            }

            string       json    = JsonSerializer.Serialize(addDependentRequest.TestDate, addDependentRequest.TestDate.GetType());
            JsonDocument jsonDoc = JsonDocument.Parse(json);

            // Insert Dependent to database
            var dependent = new ResourceDelegate()
            {
                ResourceOwnerHdid = patientResult.ResourcePayload.HdId,
                ProfileHdid       = delegateHdId,
                ReasonCode        = ResourceDelegateReason.COVIDLab,
                ReasonObjectType  = addDependentRequest.TestDate.GetType().AssemblyQualifiedName,
                ReasonObject      = jsonDoc,
            };
            DBResult <ResourceDelegate> dbDependent = this.resourceDelegateDelegate.Insert(dependent, true);

            if (dbDependent.Status == DBStatusCode.Created)
            {
                this.logger.LogTrace("Finished adding dependent");
                this.UpdateNotificationSettings(dependent.ResourceOwnerHdid, delegateHdId);

                return(new RequestResult <DependentModel>()
                {
                    ResourcePayload = DependentModel.CreateFromModels(dbDependent.Payload, patientResult.ResourcePayload),
                    ResultStatus = ResultType.Success,
                });
            }
            else
            {
                this.logger.LogError("Error adding dependent");
                return(new RequestResult <DependentModel>()
                {
                    ResourcePayload = new DependentModel(),
                    ResultStatus = ResultType.Error,
                    ResultError = new RequestResultError()
                    {
                        ResultMessage = dbDependent.Message, ErrorCode = ErrorTranslator.ServiceError(ErrorType.CommunicationInternal, ServiceType.Database)
                    },
                });
            }
        }