def make(self): sexes = ['Female', 'Male', 'Not Known', 'Not Specified'] patient = models.Patient.objects.create() demographics = patient.demographics_set.get() hospital_number = random.randint(1000, 2000000) hospital_number = str(hospital_number) demographics.first_name = random.choice(first_names) demographics.surname = random.choice(last_names) demographics.hospital_number = hospital_number demographics.nhs_number = hospital_number demographics.date_of_birth = self.get_birth_date() demographics.sex = random.choice(sexes) demographics.birth_place = foreign_key_or_free_text_generator( Demographics.birth_place ) demographics.save() self.create_episode(patient) for subrecord in episode_subrecords(): s = EpisodeSubrecordGenerator( subrecord, patient.episode_set.first() ) s.make() for subrecord in patient_subrecords(): # we've already made the demographics above if subrecord.__name__ != "Demographics": s = PatientSubrecordGenerator(subrecord, patient) s.make() return patient
def to_dict(self, user, shallow=False): """ Serialisation to JSON for Episodes """ d = { 'id' : self.id, 'category_name' : self.category_name, 'active' : self.active, 'consistency_token': self.consistency_token, 'start' : self.start, 'end' : self.end, 'stage' : self.stage, } if shallow: return d for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.patient.id) d[model.get_api_name()] = [ subrecord.to_dict(user) for subrecord in subrecords ] for model in episode_subrecords(): subrecords = model.objects.filter(episode_id=self.id) d[model.get_api_name()] = [ subrecord.to_dict(user) for subrecord in subrecords ] d['tagging'] = self.tagging_dict(user) return d
def to_dict(self, user, shallow=False): """ Serialisation to JSON for Episodes """ d = { 'id': self.id, 'category': self.category, 'active': self.active, 'date_of_admission': self.date_of_admission, 'date_of_episode': self.date_of_episode, 'discharge_date': self.discharge_date, 'consistency_token': self.consistency_token } if shallow: return d for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.patient.id) d[model.get_api_name()] = [ subrecord.to_dict(user) for subrecord in subrecords ] for model in episode_subrecords(): subrecords = model.objects.filter(episode_id=self.id) d[model.get_api_name()] = [ subrecord.to_dict(user) for subrecord in subrecords ] d['tagging'] = self.tagging_dict(user) d['episode_history'] = self._episode_history_to_dict(user) return d
def make(self): sexes = ['Female', 'Male', 'Not Known', 'Not Specified'] patient = models.Patient.objects.create() demographics = patient.demographics_set.get() hospital_number = random.randint(1000, 2000000) hospital_number = str(hospital_number) demographics.name = self.get_name() demographics.hospital_number = hospital_number demographics.nhs_number = hospital_number demographics.date_of_birth = self.get_birth_date() demographics.sex = random.choice(sexes) demographics.birth_place = foreign_key_or_free_text_generator( Demographics.birth_place) demographics.save() self.create_episode(patient) for subrecord in episode_subrecords(): s = EpisodeSubrecordGenerator(subrecord, patient.episode_set.first()) s.make() for subrecord in patient_subrecords(): # we've already made the demographics above if subrecord.__name__ != "Demographics": s = PatientSubrecordGenerator(subrecord, patient) s.make() return patient
def handle(self, *args, **options): logging.info("Creating Singletons") for subclass in patient_subrecords(): if subclass._is_singleton: to_create = [] related_name = subclass.__name__.lower() patients_to_be_updated = Patient.objects.filter( **{related_name: None}) for patient in patients_to_be_updated: logging.info('Creating {0}'.format(subclass)) to_create.append(subclass(patient=patient)) subclass.objects.bulk_create(to_create) for subclass in episode_subrecords(): if subclass._is_singleton: to_create = [] related_name = subclass.__name__.lower() episodes_to_be_updated = Episode.objects.filter( **{related_name: None}) for episode in episodes_to_be_updated: logging.info('Creating {0}'.format(subclass)) to_create.append(subclass(episode=episode)) subclass.objects.bulk_create(to_create) return
def save(self, *args, **kwargs): created = not bool(self.id) super(Patient, self).save(*args, **kwargs) if created: for subclass in patient_subrecords(): if subclass._is_singleton: subclass.objects.create(patient=self)
def to_dict(self, user, shallow=False): """ Serialisation to JSON for Episodes """ d = { 'id' : self.id, 'category' : self.category, 'active' : self.active, 'date_of_admission': self.date_of_admission, 'date_of_episode' : self.date_of_episode, 'discharge_date' : self.discharge_date, 'consistency_token': self.consistency_token } if shallow: return d for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.patient.id) d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords] for model in episode_subrecords(): subrecords = model.objects.filter(episode_id=self.id) d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords] d['tagging'] = self.tagging_dict(user) d['episode_history'] = self._episode_history_to_dict(user) return d
def save(self, *args, **kwargs): created = not bool(self.id) super(Patient, self).save(*args, **kwargs) if created: for subclass in patient_subrecords(): if subclass._is_singleton: subclass.objects.create(patient=self)
def to_dict(self, user, shallow=False): """ Serialisation to JSON for Episodes """ d = { "id": self.id, "category": self.category, "active": self.active, "date_of_admission": self.date_of_admission, "date_of_episode": self.date_of_episode, "discharge_date": self.discharge_date, "consistency_token": self.consistency_token, } if shallow: return d for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.patient.id) d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords] for model in episode_subrecords(): subrecords = model.objects.filter(episode_id=self.id) d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords] d["tagging"] = self.tagging_dict(user) d["episode_history"] = self._episode_history_to_dict(user) return d
def model_qs(self): if self.model in subrecords.patient_subrecords(): patient_ids = self.episodes.values_list( 'patient_id', flat=True ).distinct() return self.model.objects.filter(patient_id__in=patient_ids) else: episode_ids = self.episodes.values_list('id', flat=True) return self.model.objects.filter(episode_id__in=episode_ids)
def serialised(self, user, episodes, historic_tags=False, episode_history=False): """ Return a set of serialised EPISODES. If HISTORIC_TAGS is Truthy, return deleted tags as well. If EPISODE_HISTORY is Truthy return historic episodes as well. """ patient_ids = [e.patient_id for e in episodes] patient_subs = defaultdict(lambda: defaultdict(list)) episode_subs = self.serialised_episode_subrecords(episodes, user) for model in patient_subrecords(): name = model.get_api_name() subrecords = model.objects.filter(patient__in=patient_ids) for sub in subrecords: patient_subs[sub.patient_id][name].append(sub.to_dict(user)) # We do this here because it's an order of magnitude quicker than hitting # episode.tagging_dict() for each episode in a loop. taggings = defaultdict(dict) from opal.models import Tagging filter_kargs = dict(episode__in=episodes) if not historic_tags: filter_kargs["archived"] = False for tag in Tagging.objects.filter(**filter_kargs).select_related('team'): if tag.team.name == 'mine' and tag.user != user: continue taggings[tag.episode_id][tag.team.name] = True serialised = [] for e in episodes: d = { 'id' : e.id, 'category' : e.category, 'active' : e.active, 'date_of_admission': e.date_of_admission, 'date_of_episode' : e.date_of_episode, 'discharge_date' : e.discharge_date, 'consistency_token': e.consistency_token } for key, value in episode_subs[e.id].items(): d[key] = value for key, value in patient_subs[e.patient_id].items(): d[key] = value d['tagging'] = [taggings[e.id]] serialised.append(d) if episode_history: d['episode_history'] = e._episode_history_to_dict(user) return serialised
def serialised(self, user, episodes, historic_tags=False, episode_history=False): """ Return a set of serialised EPISODES. If HISTORIC_TAGS is Truthy, return deleted tags as well. If EPISODE_HISTORY is Truthy return historic episodes as well. """ patient_ids = [e.patient_id for e in episodes] patient_subs = defaultdict(lambda: defaultdict(list)) episode_subs = self.serialised_episode_subrecords(episodes, user) for model in patient_subrecords(): name = model.get_api_name() subrecords = model.objects.filter(patient__in=patient_ids) for sub in subrecords: patient_subs[sub.patient_id][name].append(sub.to_dict(user)) # We do this here because it's an order of magnitude quicker than hitting # episode.tagging_dict() for each episode in a loop. taggings = defaultdict(dict) from opal.models import Tagging qs = Tagging.objects.filter(episode__in=episodes) if not historic_tags: qs = qs.filter(archived=False) for tag in qs: if tag.value == 'mine' and tag.user != user: continue taggings[tag.episode_id][tag.value] = True serialised = [] for e in episodes: d = e.to_dict(user, shallow=True) for key, value in list(episode_subs[e.id].items()): d[key] = value for key, value in list(patient_subs[e.patient_id].items()): d[key] = value d['tagging'] = [taggings[e.id]] d['tagging'][0]['id'] = e.id serialised.append(d) if episode_history: d['episode_history'] = e._episode_history_to_dict(user) return serialised
def to_dict(self, user): active_episode = self.get_active_episode() d = { 'id': self.id, 'episodes': {episode.id: episode.to_dict(user) for episode in self.episode_set.all()}, 'active_episode_id': active_episode.id if active_episode else None, } for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.id) d[model.get_api_name()] = [subrecord.to_dict(user) for subrecord in subrecords] return d
def to_dict(self, user): d = { 'id': self.id, 'episodes': {episode.id: episode.to_dict(user) for episode in self.episode_set.all()} } for model in patient_subrecords(): subrecords = model.objects.filter(patient_id=self.id) d[model.get_api_name()] = [ subrecord.to_dict(user) for subrecord in subrecords ] return d
def serialised(self, user, episodes, historic_tags=False): """ Return a set of serialised EPISODES. If HISTORIC_TAGS is Truthy, return deleted tags as well. """ patient_ids = [e.patient_id for e in episodes] patient_subs = defaultdict(dict) episode_subs = self.serialised_episode_subrecords(episodes, user) for model in patient_subrecords(): name = model.get_api_name() for patient_id in patient_ids: patient_subs[patient_id][name] = [] subrecords = prefetch( model.objects.filter(patient__in=patient_ids) ) for sub in subrecords: patient_subs[sub.patient_id][name].append(sub.to_dict(user)) # We do this here because it's an order of magnitude quicker than # hitting episode.tagging_dict() for each episode in a loop. taggings = defaultdict(dict) from opal.models import Tagging qs = Tagging.objects.filter(episode__in=episodes) if not historic_tags: qs = qs.filter(archived=False) for tag in qs: if tag.value == 'mine' and tag.user != user: continue taggings[tag.episode_id][tag.value] = True serialised = [] for e in episodes: d = e.to_dict(user, shallow=True) for key, value in list(episode_subs[e.id].items()): d[key] = value for key, value in list(patient_subs[e.patient_id].items()): d[key] = value d['tagging'] = [taggings[e.id]] d['tagging'][0]['id'] = e.id serialised.append(d) return serialised
def record_panel( context, model, editable=1, title=None, name=None, detail_template=None, angular_filter=None, noentries=None, only_display_if_exists=False, full_width=False, ): """ Register a panel for our record. Editable is an angular expression to be evaluated """ context = copy.copy(context) if name is None: if isinstance(model, str): raise ValueError("Unable to find a subrecord") name = model.get_api_name() if detail_template is None: detail_template = model.get_detail_template() if title is None: title = model.get_display_name() ctx = { 'name': name, 'singleton': getattr(model, '_is_singleton', False), 'title': title, 'detail_template': detail_template, 'icon': model.get_icon(), 'editable': editable, 'angular_filter': angular_filter, 'noentries': noentries, 'only_display_if_exists': only_display_if_exists, 'full_width': full_width, 'is_patient_subrecord': model.__class__ in patient_subrecords() } context.dicts.append(ctx) return context
def record_panel( context, model, editable=1, title=None, name=None, detail_template=None, angular_filter=None, noentries=None, only_display_if_exists=False, full_width=False, ): """ Register a panel for our record. Editable is an angular expression to be evaluated """ context = copy.copy(context) if name is None: if isinstance(model, str): raise ValueError("Unable to find a subrecord") name = model.get_api_name() if detail_template is None: detail_template = model.get_detail_template() if title is None: title = model.get_display_name() ctx = { 'name': name, 'singleton': getattr(model, '_is_singleton', False), 'title': title, 'detail_template': detail_template, 'icon': model.get_icon(), 'editable': editable, 'angular_filter': angular_filter, 'noentries': noentries, 'only_display_if_exists': only_display_if_exists, 'full_width': full_width, 'is_patient_subrecord': model.__class__ in patient_subrecords() } context.dicts.append(ctx) return context
def zip_archive(episodes, description, user): """ Given an iterable of EPISODES, the DESCRIPTION of this set of episodes, and the USER for which we are extracting, create a zip archive suitable for download with all of these episodes as CSVs. """ target_dir = tempfile.mkdtemp() target = os.path.join(target_dir, 'extract.zip') with zipfile.ZipFile(target, mode='w') as z: zipfolder = '{0}.{1}'.format(user.username, datetime.date.today()) os.mkdir(os.path.join(target_dir, zipfolder)) make_file_path = functools.partial(os.path.join, target_dir, zipfolder) zip_relative_file_path = functools.partial(os.path.join, zipfolder) file_name = "episodes.csv" full_file_name = make_file_path(file_name) episode_csv(episodes, user, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) for subrecord in episode_subrecords(): if getattr(subrecord, '_exclude_from_extract', False): continue file_name = '{0}.csv'.format(subrecord.get_api_name()) full_file_name = make_file_path(file_name) subrecord_csv(episodes, subrecord, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) for subrecord in patient_subrecords(): if getattr(subrecord, '_exclude_from_extract', False): continue file_name = '{0}.csv'.format(subrecord.get_api_name()) full_file_name = make_file_path(file_name) patient_subrecord_csv(episodes, subrecord, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) file_name = 'filter.txt' full_file_name = make_file_path(file_name) with open(full_file_name, 'w') as description_file: description_file.write(description) z.write(full_file_name, zip_relative_file_path(file_name)) return target
def handle(self, *args, **options): logging.info("Creating Singletons") for patient in Patient.objects.all(): logging.info('Examining {0}'.format(patient)) for subclass in patient_subrecords(): if subclass._is_singleton: if subclass.objects.filter(patient=patient).count() == 0: logging.info('Creating {0}'.format(subclass)) subclass.objects.create(patient=patient) for episode in Episode.objects.all(): logging.info('Examining {0}'.format(episode)) for subclass in episode_subrecords(): if subclass._is_singleton: if subclass.objects.filter(episode=episode).count() == 0: logging.info('Creating {0}'.format(subclass)) subclass.objects.create(episode=episode) return
def handle(self, *args, **options): print "Creating Singletons" for patient in Patient.objects.all(): print 'Examining', patient for subclass in patient_subrecords(): if subclass._is_singleton: if subclass.objects.filter(patient=patient).count() == 0: print 'Creating', subclass subclass.objects.create(patient=patient) for episode in Episode.objects.all(): print 'Examining', episode for subclass in episode_subrecords(): if subclass._is_singleton: if subclass.objects.filter(episode=episode).count() == 0: print 'Creating', subclass subclass.objects.create(episode=episode) return
def get_path_and_qs_from(get_param, value, qs): subrecord = get_subrecord_from_api_name(get_param.split("__")[0]) field = get_param.split("__")[1] lookup = "{0}__{1}".format(subrecord.__name__.lower(), field) if subrecord in patient_subrecords(): lookup = "patient__{}".format(lookup) if isinstance(getattr(subrecord, field), ForeignKeyOrFreeText): if value == 'None': value = None lookup = "{}_fk".format(lookup) else: lookup = "{}_fk__name".format(lookup) path = ("{0}-{1}: {2}".format(subrecord.get_display_name(), subrecord._get_field_title(field), value)) qs = qs.filter(**{lookup: value}) return path, qs
def zip_archive(episodes, description, user): """ Given an iterable of EPISODES, the DESCRIPTION of this set of episodes, and the USER for which we are extracting, create a zip archive suitable for download with all of these episodes as CSVs. """ target_dir = tempfile.mkdtemp() target = os.path.join(target_dir, 'extract.zip') with zipfile.ZipFile(target, mode='w') as z: zipfolder = '{0}.{1}'.format(user.username, datetime.date.today()) os.mkdir(os.path.join(target_dir, zipfolder)) make_file_path = functools.partial(os.path.join, target_dir, zipfolder) zip_relative_file_path = functools.partial(os.path.join, zipfolder) file_name = "episodes.csv" full_file_name = make_file_path(file_name) episode_csv(episodes, user, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) for subrecord in episode_subrecords(): file_name = '{0}.csv'.format(subrecord.get_api_name()) full_file_name = make_file_path(file_name) subrecord_csv(episodes, subrecord, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) for subrecord in patient_subrecords(): file_name = '{0}.csv'.format(subrecord.get_api_name()) full_file_name = make_file_path(file_name) patient_subrecord_csv(episodes, subrecord, full_file_name) z.write(full_file_name, zip_relative_file_path(file_name)) file_name = 'filter.txt' full_file_name = make_file_path(file_name) with open(full_file_name, 'w') as description_file: description_file.write(description) z.write(full_file_name, zip_relative_file_path(file_name)) return target
def patient_id_to_json(patient_id, user=None, excludes=None): """ Given a PATIENT_ID return the JSON export of that patient and the patient as a tuple: return (DATA, PATIENT) If requried, pass in the active user as a kwarg. If required, pass in an interable of api_names as a kwarg to limit the subrecords you export. If the patient does not exist, raise Patient.DoesNotExist. """ patient = models.Patient.objects.get(pk=patient_id) data = patient.to_dict(user) # Remove all "id", and consistency data data = remove_keys(data, 'id', 'patient_id', 'episode_id', 'consistency_token', 'created_by_id', 'updated_by_id', 'created', 'updated') # Only include patient subrecords once - at the patient subrecord level for subrecord in subrecords.patient_subrecords(): name = subrecord.get_api_name() for episode_id, episode in data['episodes'].items(): if name in episode: del episode[name] if excludes is not None: for api_name in excludes: data = remove_keys(data, api_name) data = remove_empty_lists(data) return data, patient
def get_subrecord_qs_from_episode_qs(subrecord, queryset): if subrecord in patient_subrecords(): patients = Patient.objects.filter(episode__in=queryset) return subrecord.objects.filter(patient__in=patients) else: return subrecord.objects.filter(episode__in=queryset)
from django.core.management.base import BaseCommand from django.utils.functional import cached_property from django.utils import timezone from django.db.models import ( CharField, DateField, DateTimeField, BooleanField, TextField, NullBooleanField ) from opal import models from opal.core.fields import ForeignKeyOrFreeText from opal.core.subrecords import episode_subrecords, patient_subrecords from opal.utils import write Demographics = [ s for s in patient_subrecords() if s.get_api_name() == 'demographics' ][0] first_names = [ "Jane", "James", "Chandeep", "Samantha", "Oliver", "Charlie", "Sophie", "Emily", "Lily", "Olivia", "Amelia", "Isabella" ] last_names = [ "Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Wilson", "Brooke", "King", "Patel", "Jameson", "Davidson", "Williams" ] adjectives = [ "orange", "red", "blue", "green", "pink", "purple", "gold", "silver",
def test_get_patient_subrecords(self): patient_subrecords = [i for i in subrecords.patient_subrecords()] self.assertIn(FamousLastWords, patient_subrecords) self.assertNotIn(HatWearer, patient_subrecords)
from django.core.management.base import BaseCommand from django.utils.functional import cached_property from django.utils import timezone from django.db.models import ( CharField, DateField, DateTimeField, BooleanField, TextField, NullBooleanField ) from opal import models from opal.core.fields import ForeignKeyOrFreeText from opal.core.subrecords import episode_subrecords, patient_subrecords from opal.utils import write Demographics = [ s for s in patient_subrecords() if s.get_api_name() == 'demographics' ][0] first_names = [ "Jane", "James", "Chandeep", "Samantha", "Oliver", "Charlie", "Sophie", "Emily", "Lily", "Olivia", "Amelia", "Isabella" ] last_names = [ "Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Wilson", "Brooke", "King", "Patel", "Jameson", "Davidson", "Williams" ] adjectives = [ "orange", "red", "blue", "green", "pink", "purple", "gold", "silver",
def setUp(self): super(PatientSubrecordsTestCase, self).setUp() self.patient_subrecords = {i for i in subrecords.patient_subrecords()}
def setUp(self): super(PatientSubrecordsTestCase, self).setUp() self.patient_subrecords = {i for i in subrecords.patient_subrecords()}
class OptionAdmin(admin.ModelAdmin): form = LookupListForm ordering = ['name'] search_fields = ['name'] inlines = [SynonymInline] for model in lookuplists(): admin.site.register(model, OptionAdmin) admin.site.register(User, UserProfileAdmin) admin.site.register(models.Patient, PatientAdmin) admin.site.register(models.Episode, EpisodeAdmin) admin.site.register(models.Tagging, TaggingAdmin) for subclass in patient_subrecords(): if not subclass._meta.abstract and not getattr( subclass, "_no_admin", False): admin.site.register(subclass, PatientSubrecordAdmin) for subclass in episode_subrecords(): if not subclass._meta.abstract and not getattr( subclass, "_no_admin", False): admin.site.register(subclass, EpisodeSubrecordAdmin) admin.site.register(models.ContactNumber, MyAdmin) admin.site.register(models.Role, MyAdmin) admin.site.register(models.Macro, MyAdmin)
from optparse import make_option import random from django.core.management.base import BaseCommand from django.utils.functional import cached_property from django.utils import timezone from django.db.models import (CharField, DateField, DateTimeField, BooleanField, TextField, NullBooleanField) from opal import models from opal.core.fields import ForeignKeyOrFreeText from opal.core.subrecords import episode_subrecords, patient_subrecords from opal.utils import write Demographics = [ s for s in patient_subrecords() if s.get_api_name() == 'demographics' ][0] first_names = [ "Jane", "James", "Chandeep", "Samantha", "Oliver", "Charlie", "Sophie", "Emily", "Lily", "Olivia", "Amelia", "Isabella" ] last_names = [ "Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Wilson", "Brooke", "King", "Patel", "Jameson", "Davidson", "Williams" ] adjectives = [ "orange", "red", "blue", "green", "pink", "purple", "gold", "silver", "bronze", "ruby", "azure", "copper", "forest", "silent", "loud", "dry",
class OptionAdmin(admin.ModelAdmin): form = LookupListForm ordering = ['name'] search_fields = ['name'] inlines = [SynonymInline] for model in lookuplists(): admin.site.register(model, OptionAdmin) admin.site.register(User, UserProfileAdmin) admin.site.register(models.Patient, PatientAdmin) admin.site.register(models.Episode, EpisodeAdmin) admin.site.register(models.Tagging, TaggingAdmin) for subclass in patient_subrecords(): if not subclass._meta.abstract and not getattr(subclass, "_no_admin", False): admin.site.register(subclass, PatientSubrecordAdmin) for subclass in episode_subrecords(): if not subclass._meta.abstract and not getattr(subclass, "_no_admin", False): admin.site.register(subclass, EpisodeSubrecordAdmin) admin.site.register(models.ContactNumber, MyAdmin) admin.site.register(models.Role, MyAdmin) admin.site.register(models.Macro, MyAdmin)
def is_patient_subrecord(self): return self.subrecord in subrecords.patient_subrecords()