Skip to content

Commit

Permalink
update api functionality for the new lab test changes
Browse files Browse the repository at this point in the history
  • Loading branch information
fredkingham committed Feb 6, 2017
1 parent 57b8c26 commit 21ad0d4
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 48 deletions.
16 changes: 7 additions & 9 deletions elcid/api.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import json
from django.conf import settings

from rest_framework import viewsets
from rest_framework.response import Response
from elcid import gloss_api
from opal.core.api import (
OPALRouter, patient_from_pk, LoginRequiredViewset,
)
from opal.core.api import router as opal_api_router
from opal.core.views import _build_json_response
from opal.core.api import OPALRouter
from opal.core.api import PatientViewSet
from opal import models

Expand All @@ -20,18 +17,19 @@ def create(self, request):
gloss_api.bulk_create_from_gloss_response(request_data)
return Response("ok")


def gloss_api_query_monkey_patch(fn):
"""
Decorator that passes an episode or returns a 404 from pk kwarg.
"""
def query_api_first(self, request, pk=None):
patient = models.Patient.objects.get(pk=pk)
hospital_number = patient.demographics_set.get().hospital_number
gloss_api.patient_query(hospital_number)
if settings.GLOSS_ENABLED:
patient = models.Patient.objects.get(pk=pk)
hospital_number = patient.demographics_set.get().hospital_number
gloss_api.patient_query(hospital_number)
return fn(self, request, pk=pk)
return query_api_first


PatientViewSet.retrieve = gloss_api_query_monkey_patch(PatientViewSet.retrieve)


Expand Down
57 changes: 24 additions & 33 deletions elcid/gloss_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import logging

EXTERNAL_SYSTEM_MAPPING = {
omodels.InpatientAdmission: "Carecast",
eModels.Demographics: "Carecast",
eModels.Allergies: "ePMA"
}
Expand Down Expand Up @@ -128,6 +129,7 @@ def update_tests(update_dict):
else:
result['status'] = lmodels.LabTest.PENDING
result['date_ordered'] = result.pop('request_datetime', None)
result['lab_test_type'] = eModels.HL7Result.get_display_name()

# TODO, change date ordered to datetime ordered
if result['date_ordered']:
Expand All @@ -141,63 +143,52 @@ def update_tests(update_dict):
result['external_identifier'] = result.pop('lab_number')
result.pop('profile_code')

update_dict[eModels.HL7Result.get_api_name()] = results
update_dict[lmodels.LabTest.get_api_name()] = results
return update_dict


@transaction.atomic()
def bulk_create_from_gloss_response(request_data):
hospital_number = request_data["hospital_number"]
update_dict = request_data["messages"]
update_dict = update_tests(update_dict)
logging.info("running a bulk update with")
logging.info(update_dict)


patient_query = omodels.Patient.objects.filter(
demographics__hospital_number=hospital_number
)

if not patient_query.exists():
patient = omodels.Patient.objects.create()
patient.create_episode()
else:
patient = patient_query.get()

user = get_gloss_user()
episode_subrecords = set(
i.get_api_name() for i in subrecords.episode_subrecords()
)
episode_subrecords = {i.get_api_name() for i in subrecords.episode_subrecords()}

if update_dict:
with transaction.atomic():
# as these are only going to have been sourced from upstream
# make sure it says they're sourced from upstream
for api_name, updates_list in update_dict.iteritems():

# we use the gloss api to update patients, e.g. with the ,
# refresh patient functionality
# we don't know what episode that patient will be using
# we don't accept episode subrecords so lets
# blow up accordingly
if api_name in episode_subrecords:
raise ValueError(
"Gloss is not expected to provide episode subrecords"
)
# as these are only going to have been sourced from upstream
# make sure it says they're sourced from upstream
for api_name, updates_list in update_dict.iteritems():
if api_name in episode_subrecords:
err = "Gloss is not expected to provide episode subrecords"
err += " found {0} in {1}".format(api_name, update_dict)
raise ValueError(err)

external_system = get_external_source(api_name)
external_system = get_external_source(api_name)

if external_system:
for i in updates_list:
i["external_system"] = external_system

if "demographics" not in update_dict:
update_dict["demographics"] = [
dict(hospital_number=hospital_number)
]

results = update_dict.pop("results", None)
if external_system:
for i in updates_list:
i["external_system"] = external_system

if results:
update_dict[lmodels.HL7Result.get_api_name()] = results
if "demographics" not in update_dict:
update_dict["demographics"] = [
dict(hospital_number=hospital_number)
]

patient.bulk_update(update_dict, user, force=True)
patient.bulk_update(update_dict, user, force=True)

return patient
return patient
20 changes: 20 additions & 0 deletions elcid/test/test_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from django.test import override_settings
from mock import MagicMock, patch
from opal.core.test import OpalTestCase
from rest_framework.reverse import reverse
Expand Down Expand Up @@ -35,24 +36,29 @@ def setUp(self):
request=request
)

@override_settings(GLOSS_ENABLED=True)
def test_retrieve(self, patient_query):
patient, _ = self.new_patient_and_episode_please()
patient_query.return_value = patient
self.assertEqual(models.PatientRecordAccess.objects.count(), 0)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertTrue(patient_query.called)
self.assertEqual(models.PatientRecordAccess.objects.count(), 1)
serialised_patient = json.loads(response.content)
self.assertEqual(serialised_patient["id"], patient.id)

@override_settings(GLOSS_ENABLED=True)
def test_retrieve_not_found_in_gloss(self, patient_query):
patient, _ = self.new_patient_and_episode_please()
patient_query.return_value = None
response = self.client.get(self.url)
self.assertTrue(patient_query.called)
self.assertEqual(response.status_code, 200)
serialised_patient = json.loads(response.content)
self.assertEqual(serialised_patient["id"], patient.id)

@override_settings(GLOSS_ENABLED=True)
def test_retrieve_updates_patient_from_gloss(self, patient_query):
patient, _ = self.new_patient_and_episode_please()

Expand All @@ -63,6 +69,20 @@ def update_patient(hospital_number):

patient_query.side_effect = update_patient
response = self.client.get(self.url)
self.assertTrue(patient_query.called)
self.assertEqual(response.status_code, 200)
serialised_patient = json.loads(response.content)
self.assertEqual(
serialised_patient["demographics"][0]["first_name"],
"Indiana"
)

@override_settings(GLOSS_ENABLED=False)
def test_dont_retrieve_if_gloss_is_disabled(self, patient_query):
patient, _ = self.new_patient_and_episode_please()
patient.demographics_set.update(first_name="Indiana")
response = self.client.get(self.url)
self.assertFalse(patient_query.called)
self.assertEqual(response.status_code, 200)
serialised_patient = json.loads(response.content)
self.assertEqual(
Expand Down
19 changes: 13 additions & 6 deletions elcid/test/test_gloss_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ def run_create(self, some_dict, hospital_number="12312312"):
gloss_api.bulk_create_from_gloss_response(expected_request)

def test_with_episode_subrecords(self, *args):
err = "Gloss is not expected to provide episode "
err += "subrecords found location in {'demographics': "
err += "[{'hospital_number': '12312312', 'first_name': "
err += "'Susan', 'external_system': 'Carecast'}], "
err += "'lab_test': [], 'location': [{'ward': 'West'}]}"

request_data = {
"demographics": [{
"first_name": "Susan",
Expand All @@ -95,11 +101,11 @@ def test_with_episode_subrecords(self, *args):
}
with self.assertRaises(ValueError) as e:
self.run_create(request_data)
self.assertEqual(
str(e.exception),
'Gloss is not expected to provide episode subrecords'
)
self.assertTrue(True)

self.assertEqual(
str(e.exception),
err
)

def test_nonexisting_patient(self, *args):
request_data = {
Expand Down Expand Up @@ -344,7 +350,8 @@ def test_tests_cast(self):
"""
update_dict = gloss_api.update_tests(deepcopy(self.UPDATE_DICT))
self.assertNotIn("result", update_dict)
self.assertTrue(bool(len(update_dict["hl7_result"])))
self.assertIn("lab_test", update_dict)
self.assertEqual(update_dict["lab_test"][0]["lab_test_type"], "HL7Result")


def test_tests_update(self):
Expand Down

0 comments on commit 21ad0d4

Please sign in to comment.