Skip to content

Commit

Permalink
Merge pull request #2254 from coronasafe/develop
Browse files Browse the repository at this point in the history
Merge Develop to Staging v24.24.0
  • Loading branch information
gigincg authored Jun 7, 2024
2 parents eff9b43 + 37ab926 commit d6d55c4
Show file tree
Hide file tree
Showing 14 changed files with 721 additions and 48 deletions.
8 changes: 8 additions & 0 deletions care/facility/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
from care.facility.models.ambulance import Ambulance, AmbulanceDriver
from care.facility.models.asset import Asset
from care.facility.models.bed import AssetBed, Bed
from care.facility.models.file_upload import FileUpload
from care.facility.models.patient_consultation import (
PatientConsent,
PatientConsultation,
)
from care.facility.models.patient_sample import PatientSample

from .models import (
Expand Down Expand Up @@ -209,3 +214,6 @@ class FacilityUserAdmin(DjangoQLSearchMixin, admin.ModelAdmin, ExportCsvMixin):
admin.site.register(AssetBed)
admin.site.register(Asset)
admin.site.register(Bed)
admin.site.register(PatientConsent)
admin.site.register(FileUpload)
admin.site.register(PatientConsultation)
12 changes: 8 additions & 4 deletions care/facility/api/serializers/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
from care.facility.models.facility import Facility
from care.facility.models.file_upload import FileUpload
from care.facility.models.patient import PatientRegistration
from care.facility.models.patient_consultation import PatientConsultation
from care.facility.models.patient_consultation import (
PatientConsent,
PatientConsultation,
)
from care.facility.models.patient_sample import PatientSample
from care.users.api.serializers.user import UserBaseMinimumSerializer
from care.users.models import User
Expand Down Expand Up @@ -53,9 +56,9 @@ def check_permissions(file_type, associating_id, user, action="create"):
raise Exception("No Permission")
return consultation.id
elif file_type == FileUpload.FileType.CONSENT_RECORD.value:
consultation = PatientConsultation.objects.get(
consent_records__contains=[{"id": associating_id}]
)
consultation = PatientConsent.objects.get(
external_id=associating_id
).consultation
if consultation.discharge_date and not action == "read":
raise serializers.ValidationError(
{
Expand Down Expand Up @@ -173,6 +176,7 @@ class Meta:
fields = (
"id",
"name",
"associating_id",
"uploaded_by",
"archived_by",
"archived_datetime",
Expand Down
125 changes: 124 additions & 1 deletion care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from django.conf import settings
from django.db import transaction
from django.utils import timezone
from django.utils.timezone import localtime, make_aware, now
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
Expand Down Expand Up @@ -41,6 +42,7 @@
EncounterSymptom,
Symptom,
)
from care.facility.models.file_upload import FileUpload
from care.facility.models.icd11_diagnosis import (
ConditionVerificationStatus,
ConsultationDiagnosis,
Expand All @@ -51,7 +53,12 @@
RouteToFacility,
SuggestionChoices,
)
from care.facility.models.patient_consultation import PatientConsultation
from care.facility.models.patient_consultation import (
ConsentType,
PatientCodeStatusType,
PatientConsent,
PatientConsultation,
)
from care.users.api.serializers.user import (
UserAssignedSerializer,
UserBaseMinimumSerializer,
Expand Down Expand Up @@ -848,3 +855,119 @@ def validate(self, attrs):
class Meta:
model = PatientConsultation
fields = ("email",)


class PatientConsentSerializer(serializers.ModelSerializer):
id = serializers.CharField(source="external_id", read_only=True)
created_by = UserBaseMinimumSerializer(read_only=True)
archived_by = UserBaseMinimumSerializer(read_only=True)

class Meta:
model = PatientConsent

fields = (
"id",
"type",
"patient_code_status",
"archived",
"archived_by",
"archived_date",
"created_by",
"created_date",
)

read_only_fields = (
"id",
"created_by",
"created_date",
"archived",
"archived_by",
"archived_date",
)

def validate_patient_code_status(self, value):
if value == PatientCodeStatusType.NOT_SPECIFIED:
raise ValidationError(
"Specify a correct Patient Code Status for the Consent"
)
return value

def validate(self, attrs):
user = self.context["request"].user
if (
user.user_type < User.TYPE_VALUE_MAP["DistrictAdmin"]
and self.context["consultation"].facility_id != user.home_facility_id
):
raise ValidationError(
"Only Home Facility Staff can create consent for a Consultation"
)

if (
attrs.get("type", None)
and attrs.get("type") == ConsentType.PATIENT_CODE_STATUS
and not attrs.get("patient_code_status")
):
raise ValidationError(
{
"patient_code_status": [
"This field is required for Patient Code Status Consent"
]
}
)

if (
attrs.get("type", None)
and attrs["type"] != ConsentType.PATIENT_CODE_STATUS
and attrs.get("patient_code_status")
):
raise ValidationError(
{
"patient_code_status": [
"This field is not required for this type of Consent"
]
}
)
return attrs

def clear_existing_records(self, consultation, type, user, self_id=None):
consents = PatientConsent.objects.filter(
consultation=consultation, type=type
).exclude(id=self_id)

archived_date = timezone.now()
consents.update(
archived=True,
archived_by=user,
archived_date=archived_date,
)
FileUpload.objects.filter(
associating_id__in=list(consents.values_list("external_id", flat=True)),
file_type=FileUpload.FileType.CONSENT_RECORD,
is_archived=False,
).update(
is_archived=True,
archived_datetime=archived_date,
archive_reason="Consent Archived",
archived_by=user,
)

def create(self, validated_data):
with transaction.atomic():
self.clear_existing_records(
consultation=self.context["consultation"],
type=validated_data["type"],
user=self.context["request"].user,
)
validated_data["consultation"] = self.context["consultation"]
validated_data["created_by"] = self.context["request"].user
return super().create(validated_data)

def update(self, instance, validated_data):
with transaction.atomic():
self.clear_existing_records(
consultation=instance.consultation,
type=instance.type,
user=self.context["request"].user,
self_id=instance.id,
)
return super().update(instance, validated_data)
16 changes: 11 additions & 5 deletions care/facility/api/viewsets/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,19 @@ def get_queryset(self):
{"associating_id": "associating_id missing in request params"}
)
file_type = self.request.GET["file_type"]
associating_id = self.request.GET["associating_id"]
associating_ids = self.request.GET["associating_id"].split(",")
if file_type not in FileUpload.FileType.__members__:
raise ValidationError({"file_type": "invalid file type"})
file_type = FileUpload.FileType[file_type].value
associating_internal_id = check_permissions(
file_type, associating_id, self.request.user, "read"
)

associating_internal_ids = []

for associating_id in associating_ids:
associating_internal_id = check_permissions(
file_type, associating_id, self.request.user, "read"
)
associating_internal_ids.append(associating_internal_id)

return self.queryset.filter(
file_type=file_type, associating_id=associating_internal_id
file_type=file_type, associating_id__in=associating_internal_ids
)
5 changes: 4 additions & 1 deletion care/facility/api/viewsets/icd.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ def list(self, request):
except (ValueError, TypeError):
limit = 20

query = [ICD11.has_code == 1]
query = [
ICD11.has_code == 1,
ICD11.chapter != "null", # noqa: E711
]
if q := request.query_params.get("query"):
query.append(ICD11.vec % query_builder(q))

Expand Down
44 changes: 42 additions & 2 deletions care/facility/api/viewsets/patient_consultation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db.models import Prefetch
from django.db.models.query_utils import Q
from django.shortcuts import render
from django.shortcuts import get_object_or_404, render
from django_filters import rest_framework as filters
from drf_spectacular.utils import extend_schema
from dry_rest_permissions.generics import DRYPermissions
Expand All @@ -14,6 +14,7 @@
from care.facility.api.serializers.file_upload import FileUploadRetrieveSerializer
from care.facility.api.serializers.patient_consultation import (
EmailDischargeSummarySerializer,
PatientConsentSerializer,
PatientConsultationDischargeSerializer,
PatientConsultationIDSerializer,
PatientConsultationSerializer,
Expand All @@ -22,14 +23,18 @@
from care.facility.models.bed import AssetBed, ConsultationBed
from care.facility.models.file_upload import FileUpload
from care.facility.models.mixins.permissions.asset import IsAssetUser
from care.facility.models.patient_consultation import PatientConsultation
from care.facility.models.patient_consultation import (
PatientConsent,
PatientConsultation,
)
from care.facility.tasks.discharge_summary import (
email_discharge_summary_task,
generate_discharge_summary_task,
)
from care.facility.utils.reports import discharge_summary
from care.users.models import Skill, User
from care.utils.cache.cache_allowed_facilities import get_accessible_facilities
from care.utils.queryset.consultation import get_consultation_queryset


class PatientConsultationFilter(filters.FilterSet):
Expand Down Expand Up @@ -287,3 +292,38 @@ def dev_preview_discharge_summary(request, consultation_id):
raise NotFound({"detail": "Consultation not found"})
data = discharge_summary.get_discharge_summary_data(consultation)
return render(request, "reports/patient_discharge_summary_pdf.html", data)


class PatientConsentViewSet(
AssetUserAccessMixin,
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericViewSet,
):
lookup_field = "external_id"
serializer_class = PatientConsentSerializer
permission_classes = (
IsAuthenticated,
DRYPermissions,
)
queryset = PatientConsent.objects.all().select_related("consultation")
filter_backends = (filters.DjangoFilterBackend,)

filterset_fields = ("archived",)

def get_consultation_obj(self):
return get_object_or_404(
get_consultation_queryset(self.request.user).filter(
external_id=self.kwargs["consultation_external_id"]
)
)

def get_queryset(self):
return self.queryset.filter(consultation=self.get_consultation_obj())

def get_serializer_context(self):
data = super().get_serializer_context()
data["consultation"] = self.get_consultation_obj()
return data
Loading

0 comments on commit d6d55c4

Please sign in to comment.