Skip to content

Commit

Permalink
complete?
Browse files Browse the repository at this point in the history
  • Loading branch information
shivankacker committed May 30, 2024
1 parent eb7c358 commit 0724813
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 51 deletions.
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
39 changes: 27 additions & 12 deletions care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ class Meta:
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
Expand All @@ -882,6 +883,8 @@ class Meta:
"type",
"patient_code_status",
"archived",
"archived_by",
"archived_date",
"created_by",
"created_date",
)
Expand All @@ -890,19 +893,31 @@ class Meta:
"id",
"created_by",
"created_date",
"archived",
"archived_by",
"archived_date",
)

def update(self, instance, validated_data):
# check if the consent has been archived, if so, cascade archive all files
if instance.archived:
for file in instance.files.all():
file.is_archived = True
file.archive_reason = instance.archived_reason
file.archive_datetime = timezone.now()
file.save()
def clear_existing_records(self, consultation, type, self_id=None):
consents = PatientConsent.objects.filter(
consultation=consultation, type=type
).exclude(id=self_id)

# looping because .update does not call model save method
for consent in consents:
consent.archived = True
consent.archived_by = self.context["request"].user
consent.archived_date = timezone.now()
consent.save()

return super().update(instance, validated_data)
def create(self, validated_data):
self.clear_existing_records(
consultation=validated_data["consultation"], type=validated_data["type"]
)
return super().create(validated_data)

def create(self, validated_data):
validated_data["created_by"] = self.context["request"].user
return super().create(validated_data)
def update(self, instance, validated_data):
self.clear_existing_records(
consultation=instance.consultation, type=instance.type, 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
)
11 changes: 11 additions & 0 deletions care/facility/api/viewsets/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,14 @@ class PatientConsentViewSet(
)
queryset = PatientConsent.objects.all().select_related("consultation")
filter_backends = (filters.DjangoFilterBackend,)

filterset_fields = ("archived",)

def get_queryset(self):
consultation_id = self.kwargs.get("consultation_external_id", None)
return self.queryset.filter(consultation__external_id=consultation_id)

def perform_create(self, serializer):
consultation_id = self.kwargs.get("consultation_external_id", None)
consultation = PatientConsultation.objects.get(external_id=consultation_id)
serializer.save(consultation=consultation, created_by=self.request.user)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.2.10 on 2024-05-30 06:33
# Generated by Django 4.2.10 on 2024-05-30 16:35

import uuid

Expand All @@ -7,6 +7,7 @@
from django.db import migrations, models
from django.utils import timezone

import care.facility.models.mixins.permissions.patient
from care.facility.models.file_upload import FileUpload as FileUploadModel
from care.facility.models.patient_consultation import (
PatientConsent as PatientConsentModel,
Expand Down Expand Up @@ -60,8 +61,6 @@ def migrate_consents(apps, schema_editor):

files.update(**kwargs)

new_consent.files.add(*files)

def reverse_migrate(apps, schema_editor):
PatientConsent: PatientConsentModel = apps.get_model(
"facility", "PatientConsent"
Expand Down Expand Up @@ -121,9 +120,9 @@ def reverse_migrate(apps, schema_editor):
"type",
models.IntegerField(
choices=[
(1, "Consent For Admission"),
(1, "Consent for Admission"),
(2, "Patient Code Status"),
(3, "Consent For Procedure"),
(3, "Consent for Procedure"),
(4, "High Risk Consent"),
(5, "Others"),
]
Expand All @@ -134,15 +133,26 @@ def reverse_migrate(apps, schema_editor):
models.IntegerField(
blank=True,
choices=[
(1, "Dnh"),
(2, "Dnr"),
(3, "Comfort Care"),
(1, "Do Not Hospitalize"),
(2, "Do Not Resuscitate"),
(3, "Comfort Care Only"),
(4, "Active Treatment"),
],
null=True,
),
),
("archived", models.BooleanField(default=False)),
("archived_date", models.DateTimeField(blank=True, null=True)),
(
"archived_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name="archived_consents",
to=settings.AUTH_USER_MODEL,
),
),
(
"consultation",
models.ForeignKey(
Expand All @@ -158,16 +168,19 @@ def reverse_migrate(apps, schema_editor):
to=settings.AUTH_USER_MODEL,
),
),
(
"files",
models.ManyToManyField(
related_name="consents", to="facility.fileupload"
),
),
],
options={
"abstract": False,
},
bases=(
models.Model,
care.facility.models.mixins.permissions.patient.ConsultationRelatedPermissionMixin,
),
),
migrations.AddConstraint(
model_name="patientconsent",
constraint=models.UniqueConstraint(
condition=models.Q(("archived", False)),
fields=("consultation", "type"),
name="unique_consultation_consent",
),
),
migrations.RunPython(migrate_consents, reverse_code=reverse_migrate),
migrations.RemoveField(
Expand Down
2 changes: 1 addition & 1 deletion care/facility/models/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,4 @@ class FileType(models.IntegerChoices):
FileCategoryChoices = [(x.value, x.name) for x in BaseFileUpload.FileCategory]

def __str__(self):
return f"{self.FileTypeChoices[self.file_type][1]} - {self.name}"
return f"{self.FileTypeChoices[self.file_type][1]} - {self.name}{' (Archived)' if self.is_archived else ''}"
82 changes: 71 additions & 11 deletions care/facility/models/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,30 +390,90 @@ class ConsultationClinician(models.Model):
)


class PatientConsent(BaseModel):
class PatientConsent(BaseModel, ConsultationRelatedPermissionMixin):
consultation = models.ForeignKey(PatientConsultation, on_delete=models.CASCADE)
type = models.IntegerField(choices=ConsentType.choices)
patient_code_status = models.IntegerField(
choices=PatientCodeStatusType.choices, null=True, blank=True
)
archived = models.BooleanField(default=False)
files = models.ManyToManyField(FileUpload, related_name="consents")
archived_by = models.ForeignKey(
User,
on_delete=models.PROTECT,
null=True,
blank=True,
related_name="archived_consents",
)
archived_date = models.DateTimeField(null=True, blank=True)
created_by = models.ForeignKey(
User, on_delete=models.PROTECT, related_name="created_consents"
)

class Meta:
constraints = [
models.UniqueConstraint(
fields=["consultation", "type"],
name="unique_consultation_consent",
condition=models.Q(archived=False),
)
]

def __str__(self) -> str:
return f"{self.consultation.patient.name} - {ConsentType(self.type).label}"
return f"{self.consultation.patient.name} - {ConsentType(self.type).label}{' (Archived)' if self.archived else ''}"

def save(self, *args, **kwargs):
# archive existing patient code status consent
if self.pk is None and self.type == ConsentType.PATIENT_CODE_STATUS:
existing_pcs = PatientConsent.objects.filter(
consultation=self.consultation,
type=ConsentType.PATIENT_CODE_STATUS,
archived=False,
if self.archived:
files = FileUpload.objects.filter(
associating_id=self.external_id,
is_archived=False,
)
files.update(
is_archived=True,
archived_datetime=timezone.now(),
archive_reason="Consent Archived",
archived_by=self.archived_by,
)
if existing_pcs.exists():
existing_pcs.update(archived=True)

super().save(*args, **kwargs)

@staticmethod
def has_write_permission(request):
return request.user.is_superuser or (
request.user.verified
and ConsultationRelatedPermissionMixin.has_write_permission(request)
)

def has_object_read_permission(self, request):
if not super().has_object_read_permission(request):
return False
return (
request.user.is_superuser
or (
self.patient.facility
and request.user in self.consultation.patient.facility.users.all()
)
or (
self.consultation.assigned_to == request.user
or request.user == self.consultation.patient.assigned_to
)
or (
request.user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]
and (
self.consultation.patient.facility
and request.user.district
== self.consultation.patient.facility.district
)
)
or (
request.user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]
and (
self.consultation.patient.facility
and request.user.state == self.consultation.patient.facility.state
)
)
)

def has_object_update_permission(self, request):
return super().has_object_update_permission(
request
) and self.has_object_read_permission(request)
6 changes: 5 additions & 1 deletion config/api_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@
PatientSearchViewSet,
PatientViewSet,
)
from care.facility.api.viewsets.patient_consultation import PatientConsultationViewSet
from care.facility.api.viewsets.patient_consultation import (
PatientConsentViewSet,
PatientConsultationViewSet,
)
from care.facility.api.viewsets.patient_external_test import PatientExternalTestViewSet
from care.facility.api.viewsets.patient_investigation import (
InvestigationGroupViewset,
Expand Down Expand Up @@ -234,6 +237,7 @@
consultation_nested_router.register(
r"prescription_administration", MedicineAdministrationViewSet
)
consultation_nested_router.register(r"consents", PatientConsentViewSet)
consultation_nested_router.register(r"events", PatientConsultationEventViewSet)

router.register("event_types", EventTypeViewSet)
Expand Down

0 comments on commit 0724813

Please sign in to comment.