radar/api/views/consultants.py
from cornflake import fields, serializers
from sqlalchemy.orm import aliased
from radar.api.permissions import AdminPermission
from radar.api.serializers.consultants import ConsultantSerializer, SpecialtySerializer
from radar.api.views.generics import (
CreateModelView,
DestroyModelView,
ListModelView,
parse_args,
RetrieveModelView,
UpdateModelView,
)
from radar.auth.sessions import current_user
from radar.database import db
from radar.models.consultants import Consultant, GroupConsultant, Specialty
from radar.models.groups import Group, GroupPatient
from radar.models.patients import Patient
from radar.patient_search import PatientQueryBuilder
class ConsultantRequestSerializer(serializers.Serializer):
patient = fields.IntegerField(required=False)
def filter_consultants_by_patient_id(query, patient_id):
# Only return consultants that belong to one of the groups the patient also belongs to
consultant_alias = aliased(Consultant)
consultants_for_patient_query = db.session.query(consultant_alias)
consultants_for_patient_query = consultants_for_patient_query.join(consultant_alias.group_consultants)
consultants_for_patient_query = consultants_for_patient_query.join(GroupConsultant.group)
consultants_for_patient_query = consultants_for_patient_query.join(Group.group_patients)
consultants_for_patient_query = consultants_for_patient_query.filter(
GroupPatient.patient_id == patient_id,
Consultant.id == consultant_alias.id,
)
query = query.filter(consultants_for_patient_query.exists())
# Check the user has permission to view this patient
patient_query = PatientQueryBuilder(current_user).build()
patient_query = patient_query.filter(Patient.id == patient_id)
query = query.filter(patient_query.exists())
return query
class ConsultantListView(ListModelView):
serializer_class = ConsultantSerializer
model_class = Consultant
def filter_query(self, query):
query = super(ConsultantListView, self).filter_query(query)
args = parse_args(ConsultantRequestSerializer)
# Only show the consultants available to a patient
if args['patient'] is not None:
patient_id = args['patient']
query = filter_consultants_by_patient_id(query, patient_id)
return query
class ConsultantCreateView(CreateModelView):
serializer_class = ConsultantSerializer
model_class = Consultant
permissions = [AdminPermission]
class ConsultantRetrieveView(RetrieveModelView):
serializer_class = ConsultantSerializer
model_class = Consultant
class ConsultantUpdateView(UpdateModelView):
serializer_class = ConsultantSerializer
model_class = Consultant
permissions = [AdminPermission]
class ConsultantDestroyView(DestroyModelView):
serializer_class = ConsultantSerializer
model_class = Consultant
permissions = [AdminPermission]
class SpecialtyListView(ListModelView):
serializer_class = SpecialtySerializer
model_class = Specialty
def register_views(app):
app.add_url_rule('/consultants', view_func=ConsultantListView.as_view('consultant_list'))
app.add_url_rule('/consultants', view_func=ConsultantCreateView.as_view('consultant_create'))
app.add_url_rule('/consultants/<id>', view_func=ConsultantRetrieveView.as_view('consultant_retrieve'))
app.add_url_rule('/consultants/<id>', view_func=ConsultantUpdateView.as_view('consultant_update'))
app.add_url_rule('/consultants/<id>', view_func=ConsultantDestroyView.as_view('consultant_destroy'))
app.add_url_rule('/specialties', view_func=SpecialtyListView.as_view('specialty_list'))