use of uk.gov.hscic.model.patient.PatientDetails in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method registerPatient.
@Operation(name = REGISTER_PATIENT_OPERATION_NAME)
public Bundle registerPatient(@ResourceParam Parameters params) {
Patient registeredPatient = null;
validateParameterNames(params, registerPatientParams);
Patient unregisteredPatient = params.getParameter().stream().filter(param -> "registerPatient".equalsIgnoreCase(param.getName())).map(ParametersParameterComponent::getResource).map(Patient.class::cast).findFirst().orElse(null);
String nnn = nhsNumber.fromPatientResource(unregisteredPatient);
// if its patient 14 spoof not on PDS and return the required error
if (nnn.equals(patientNotOnSpine)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) not present on PDS", nnn)), SystemCode.INVALID_PATIENT_DEMOGRAPHICS, IssueType.INVALID);
} else if (nnn.equals(patientSuperseded)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) is superseded", nnn)), SystemCode.INVALID_NHS_NUMBER, IssueType.INVALID);
}
if (unregisteredPatient != null) {
validatePatient(unregisteredPatient);
// check if the patient already exists
PatientDetails patientDetails = patientSearch.findPatient(nhsNumber.fromPatientResource(unregisteredPatient));
if (patientDetails == null || IsInactiveTemporaryPatient(patientDetails)) {
if (patientDetails == null) {
patientDetails = registerPatientResourceConverterToPatientDetail(unregisteredPatient);
patientStore.create(patientDetails);
} else {
// reactivate inactive non temporary patient
patientDetails.setRegistrationStatus(ACTIVE_REGISTRATION_STATUS);
updateAddressAndTelecom(unregisteredPatient, patientDetails);
patientStore.update(patientDetails);
}
try {
registeredPatient = patientDetailsToRegisterPatientResourceConverter(patientSearch.findPatient(unregisteredPatient.getIdentifierFirstRep().getValue()));
addPreferredBranchSurgeryExtension(registeredPatient);
} catch (FHIRException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (patientDetails.isDeceased() || patientDetails.isSensitive()) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) has invalid demographics", nnn)), SystemCode.INVALID_PATIENT_DEMOGRAPHICS, IssueType.INVALID);
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(409, String.format("Patient (NHS number - %s) already exists", nnn)), SystemCode.DUPLICATE_REJECTED, IssueType.INVALID);
}
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Patient record not found"), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
Bundle bundle = new Bundle().setType(BundleType.SEARCHSET);
bundle.getMeta().addProfile(SystemURL.SD_GPC_SRCHSET_BUNDLE);
bundle.addEntry().setResource(registeredPatient);
return bundle;
}
use of uk.gov.hscic.model.patient.PatientDetails in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method getPatientById.
@Read(version = true)
public Patient getPatientById(@IdParam IdType internalId) throws FHIRException {
PatientDetails patientDetails = patientSearch.findPatientByInternalID(internalId.getIdPart());
if (patientDetails == null || patientDetails.isSensitive() || patientDetails.isDeceased() || !patientDetails.isActive()) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException("No patient details found for patient ID: " + internalId.getIdPart()), SystemCode.PATIENT_NOT_FOUND, IssueType.NOTFOUND);
}
Patient patient = IdentifierValidator.versionComparison(internalId, patientDetailsToPatientResourceConverter(patientDetails));
if (null != patient) {
addPreferredBranchSurgeryExtension(patient);
}
return patient;
}
use of uk.gov.hscic.model.patient.PatientDetails in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method StructuredRecordOperation.
@Operation(name = GET_STRUCTURED_RECORD_OPERATION_NAME)
public Bundle StructuredRecordOperation(@ResourceParam Parameters params) throws FHIRException {
Bundle structuredBundle = new Bundle();
Boolean getAllergies = false;
Boolean includeResolved = false;
Boolean getMedications = false;
Boolean includePrescriptionIssues = false;
Period medicationPeriod = null;
String NHS = getNhsNumber(params);
PatientDetails patientDetails = patientSearch.findPatient(NHS);
// see https://nhsconnect.github.io/gpconnect/accessrecord_structured_development_retrieve_patient_record.html#error-handling
if (patientDetails == null || patientDetails.isSensitive() || patientDetails.isDeceased() || !patientDetails.isActive()) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException("No patient details found for patient ID: " + NHS), SystemCode.PATIENT_NOT_FOUND, IssueType.NOTFOUND);
}
if (NHS.equals(patientNoconsent)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new ForbiddenOperationException("No patient consent to share for patient ID: " + NHS), SystemCode.NO_PATIENT_CONSENT, IssueType.FORBIDDEN);
}
operationOutcome = null;
for (ParametersParameterComponent param : params.getParameter()) {
if (validateParametersName(param.getName())) {
if (param.getName().equals(SystemConstants.INCLUDE_ALLERGIES)) {
getAllergies = true;
if (param.getPart().isEmpty()) {
// addWarningIssue(param, IssueType.REQUIRED, "Miss parameter part : " + SystemConstants.INCLUDE_RESOLVED_ALLERGIES);
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Miss parameter : " + SystemConstants.INCLUDE_RESOLVED_ALLERGIES), SystemCode.INVALID_PARAMETER, IssueType.REQUIRED);
}
boolean includeResolvedParameterPartPresent = false;
for (ParametersParameterComponent paramPart : param.getPart()) {
if (paramPart.getName().equals(SystemConstants.INCLUDE_RESOLVED_ALLERGIES)) {
if (paramPart.getValue() instanceof BooleanType) {
includeResolved = Boolean.valueOf(paramPart.getValue().primitiveValue());
includeResolvedParameterPartPresent = true;
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Miss parameter : " + SystemConstants.INCLUDE_RESOLVED_ALLERGIES), SystemCode.INVALID_PARAMETER, IssueType.REQUIRED);
}
} else {
addWarningIssue(param, paramPart, IssueType.NOTSUPPORTED);
// throw OperationOutcomeFactory.buildOperationOutcomeException(
// new UnprocessableEntityException("Incorrect parameter passed : " + paramPart.getName()),
// SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
}
if (!includeResolvedParameterPartPresent) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Miss parameter : " + SystemConstants.INCLUDE_RESOLVED_ALLERGIES), SystemCode.INVALID_PARAMETER, IssueType.REQUIRED);
}
}
if (param.getName().equals(SystemConstants.INCLUDE_MEDICATION)) {
getMedications = true;
boolean isIncludedPrescriptionIssuesExist = false;
for (ParametersParameterComponent paramPart : param.getPart()) {
if (paramPart.getName().equals(SystemConstants.INCLUDE_PRESCRIPTION_ISSUES)) {
if (paramPart.getValue() instanceof BooleanType) {
includePrescriptionIssues = Boolean.valueOf(paramPart.getValue().primitiveValue());
isIncludedPrescriptionIssuesExist = true;
}
} else if (paramPart.getName().equals(SystemConstants.MEDICATION_SEARCH_FROM_DATE) && paramPart.getValue() instanceof DateType) {
DateType startDateDt = (DateType) paramPart.getValue();
medicationPeriod = new Period();
medicationPeriod.setStart(startDateDt.getValue());
medicationPeriod.setEnd(null);
String startDate = startDateDt.asStringValue();
if (!validateStartDateParamAndEndDateParam(startDate, null)) {
// addWarningIssue(param, paramPart, IssueType.INVALID, "Invalid date used");
}
} else {
addWarningIssue(param, paramPart, IssueType.NOTSUPPORTED);
// throw OperationOutcomeFactory.buildOperationOutcomeException(
// new UnprocessableEntityException("Incorrect parameter passed : " + paramPart.getName()),
// SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
}
if (!isIncludedPrescriptionIssuesExist) {
// # 1.2.6 now defaults to true if not provided
includePrescriptionIssues = true;
}
}
} else {
// invalid parameter
addWarningIssue(param, IssueType.NOTSUPPORTED);
}
}
// for parameter
// Add Patient
Patient patient = patientDetailsToPatientResourceConverter(patientDetails);
if (patient.getIdentifierFirstRep().getValue().equals(NHS)) {
structuredBundle.addEntry().setResource(patient);
}
// Organization from patient
Set<String> orgIds = new HashSet<>();
orgIds.add(patientDetails.getManagingOrganization());
// Practitioner from patient
Set<String> practitionerIds = new HashSet<>();
List<Reference> practitionerReferenceList = patient.getGeneralPractitioner();
practitionerReferenceList.forEach(practitionerReference -> {
String[] pracRef = practitionerReference.getReference().split("/");
if (pracRef.length > 1) {
practitionerIds.add(pracRef[1]);
}
});
if (getAllergies) {
structuredBundle = structuredAllergyIntoleranceBuilder.buildStructuredAllergyIntolerence(NHS, practitionerIds, structuredBundle, includeResolved);
}
if (getMedications) {
structuredBundle = populateMedicationBundle.addMedicationBundleEntries(structuredBundle, patientDetails, includePrescriptionIssues, medicationPeriod, practitionerIds, orgIds);
}
// Add all practitioners and practitioner roles
for (String practitionerId : practitionerIds) {
Practitioner pracResource = practitionerResourceProvider.getPractitionerById(new IdType(practitionerId));
structuredBundle.addEntry().setResource(pracResource);
List<PractitionerRole> practitionerRoleList = practitionerRoleResourceProvider.getPractitionerRoleByPracticionerId(new IdType(practitionerId));
for (PractitionerRole role : practitionerRoleList) {
String[] split = role.getOrganization().getReference().split("/");
orgIds.add(split[1]);
structuredBundle.addEntry().setResource(role);
}
}
// Add all organizations
for (String orgId : orgIds) {
OrganizationDetails organizationDetails = organizationSearch.findOrganizationDetails(new Long(orgId));
Organization organization = organizationResourceProvider.convertOrganizationDetailsToOrganization(organizationDetails);
structuredBundle.addEntry().setResource(organization);
}
structuredBundle.setType(BundleType.COLLECTION);
structuredBundle.getMeta().addProfile(SystemURL.SD_GPC_STRUCTURED_BUNDLE);
if (operationOutcome != null) {
structuredBundle.addEntry().setResource(operationOutcome);
} else {
removeDuplicateResources(structuredBundle);
}
return structuredBundle;
}
use of uk.gov.hscic.model.patient.PatientDetails in project gpconnect-demonstrator by nhsconnect.
the class AppointmentValidation method validateParticipantActor.
/**
* check the resource exists
* @param participantActor
*/
public void validateParticipantActor(Reference participantActor) {
String resourcePart = participantActor.getReference().replaceFirst("^(.*)/.*$", "$1");
idPart = participantActor.getReference().replaceFirst("^.*/(.*)$", "$1");
Boolean participantFailedSearch = false;
switch(resourcePart) {
case "Patient":
PatientDetails patient = patientSearch.findPatientByInternalID(idPart);
participantFailedSearch = (patient == null);
break;
case "Practitioner":
PractitionerDetails practitioner = practitionerSearch.findPractitionerDetails(idPart);
participantFailedSearch = (practitioner == null);
break;
case "Location":
LocationDetails location = locationSearch.findLocationById(idPart);
participantFailedSearch = (location == null);
break;
default:
System.err.println("Unhandled resourcePart " + resourcePart);
}
if (participantFailedSearch) {
throwUnprocessableEntity422_InvalidResourceException(String.format("%s resource reference %s is not a valid resource", resourcePart, idPart));
}
}
use of uk.gov.hscic.model.patient.PatientDetails in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method registerPatientResourceConverterToPatientDetail.
private PatientDetails registerPatientResourceConverterToPatientDetail(Patient patientResource) {
PatientDetails patientDetails = new PatientDetails();
HumanName name = patientResource.getNameFirstRep();
String givenNames = name.getGiven().stream().map(n -> n.getValue()).collect(Collectors.joining(","));
patientDetails.setForename(givenNames);
patientDetails.setSurname(name.getFamily());
patientDetails.setDateOfBirth(patientResource.getBirthDate());
if (patientResource.getGender() != null) {
patientDetails.setGender(patientResource.getGender().toString());
}
patientDetails.setNhsNumber(patientResource.getIdentifierFirstRep().getValue());
DateTimeType deceased = (DateTimeType) patientResource.getDeceased();
if (deceased != null) {
try {
patientDetails.setDeceased((deceased.getValue()));
} catch (ClassCastException cce) {
throwUnprocessableEntity422_InvalidResourceException("The multiple deceased property is expected to be a datetime");
}
}
// activate patient as temporary
patientDetails.setRegistrationStartDateTime(new Date());
// patientDetails.setRegistrationEndDateTime(getRegistrationEndDate(patientResource));
patientDetails.setRegistrationStatus(ACTIVE_REGISTRATION_STATUS);
patientDetails.setRegistrationType(TEMPORARY_RESIDENT_REGISTRATION_TYPE);
updateAddressAndTelecom(patientResource, patientDetails);
// set some standard values for defaults, ensure managing org is always returned
// added at 1.2.2 7 is A20047 the default GP Practice
patientDetails.setManagingOrganization("7");
return patientDetails;
}
Aggregations