Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return files with consent lists and consent filters #2255

Merged
merged 10 commits into from
Jul 13, 2024
20 changes: 20 additions & 0 deletions care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,7 @@
id = serializers.CharField(source="external_id", read_only=True)
created_by = UserBaseMinimumSerializer(read_only=True)
archived_by = UserBaseMinimumSerializer(read_only=True)
files = serializers.SerializerMethodField()

class Meta:
model = PatientConsent
Expand All @@ -869,6 +870,7 @@
"id",
"type",
"patient_code_status",
"files",
"archived",
"archived_by",
"archived_date",
Expand All @@ -878,13 +880,31 @@

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

def get_files(self, obj):
from care.facility.api.serializers.file_upload import (
FileUploadListSerializer,
check_permissions,
)

user = self.context["request"].user
file_type = FileUpload.FileType.CONSENT_RECORD
if check_permissions(file_type, obj.external_id, user, "read"):
return FileUploadListSerializer(
FileUpload.objects.filter(
associating_id=obj.external_id, file_type=file_type
),
many=True,
).data
return None

Check warning on line 906 in care/facility/api/serializers/patient_consultation.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_consultation.py#L906

Added line #L906 was not covered by tests

def validate_patient_code_status(self, value):
if value == PatientCodeStatusType.NOT_SPECIFIED:
raise ValidationError(
Expand Down
53 changes: 52 additions & 1 deletion care/facility/api/viewsets/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
)
from care.facility.models.base import covert_choice_dict
from care.facility.models.bed import AssetBed
from care.facility.models.file_upload import FileUpload
from care.facility.models.icd11_diagnosis import (
INACTIVE_CONDITION_VERIFICATION_STATUSES,
ConditionVerificationStatus,
Expand All @@ -78,7 +79,10 @@
DISEASE_STATUS_DICT,
NewDischargeReasonEnum,
)
from care.facility.models.patient_consultation import PatientConsultation
from care.facility.models.patient_consultation import (
PatientConsent,
PatientConsultation,
)
from care.users.models import User
from care.utils.cache.cache_allowed_facilities import get_accessible_facilities
from care.utils.filters.choicefilter import CareChoiceFilter
Expand Down Expand Up @@ -279,6 +283,53 @@
)
return queryset.filter(filter_q)

last_consultation__consent_types = MultiSelectFilter(
method="filter_by_has_consents"
)

def filter_by_has_consents(self, queryset, name, value: str):
shivankacker marked this conversation as resolved.
Show resolved Hide resolved

if not value:
return queryset

Check warning on line 293 in care/facility/api/viewsets/patient.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/patient.py#L293

Added line #L293 was not covered by tests

values = value.split(",")

filter_q = Q()

consultation_consent_files = (
FileUpload.objects.filter(
file_type=FileUpload.FileType.CONSENT_RECORD,
is_archived=False,
)
.order_by("associating_id")
.distinct("associating_id")
shivankacker marked this conversation as resolved.
Show resolved Hide resolved
.values_list("associating_id", flat=True)
)

consultations = PatientConsent.objects.filter(
external_id__in=[x for x in list(consultation_consent_files)],
shivankacker marked this conversation as resolved.
Show resolved Hide resolved
archived=False,
)

if "None" in values:
filter_q |= ~Q(
last_consultation__id__in=list(
consultations.values_list("consultation_id", flat=True)
)
shivankacker marked this conversation as resolved.
Show resolved Hide resolved
)
values.remove("None")

if values:
filter_q |= Q(
last_consultation__id__in=list(
shivankacker marked this conversation as resolved.
Show resolved Hide resolved
consultations.filter(type__in=values).values_list(
"consultation_id", flat=True
)
)
)

return queryset.filter(filter_q)


class PatientDRYFilter(DRYPermissionFiltersBase):
def filter_queryset(self, request, queryset, view):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 4.2.10 on 2024-06-23 19:13

from django.db import migrations, models


class Migration(migrations.Migration):

def migrate_has_consents(apps, schema_editor):
PatientRegistration = apps.get_model("facility", "PatientRegistration")
FileUpload = apps.get_model("facility", "FileUpload")
PatientConsent = apps.get_model("facility", "PatientConsent")
for patient_registration in PatientRegistration.objects.all():
consents = PatientConsent.objects.filter(
consultation__patient=patient_registration, archived=False
).values_list("external_id", flat=True)
uuid_array = [str(uuid) for uuid in consents]
has_consents = FileUpload.objects.filter(
associating_id__in=uuid_array,
file_type=7,
is_archived=False,
).exists()
patient_registration.has_consents = has_consents
patient_registration.save()

dependencies = [
("facility", "0443_remove_patientconsultation_consent_records_and_more"),
]

operations = [
migrations.AddField(
model_name="historicalpatientregistration",
name="has_consents",
field=models.BooleanField(
default=False, verbose_name="Patient has consent files"
),
),
migrations.AddField(
model_name="patientregistration",
name="has_consents",
field=models.BooleanField(
default=False, verbose_name="Patient has consent files"
),
),
migrations.RunPython(
migrate_has_consents, reverse_code=migrations.RunPython.noop
),
]
19 changes: 19 additions & 0 deletions care/facility/models/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,24 @@ class FileType(models.IntegerChoices):
FileTypeChoices = [(x.value, x.name) for x in FileType]
FileCategoryChoices = [(x.value, x.name) for x in BaseFileUpload.FileCategory]

def save(self, *args, **kwargs):
from care.facility.models import PatientConsent # here to avoid circular import

if self.file_type == self.FileType.CONSENT_RECORD:
other_files = FileUpload.objects.filter(
associating_id=self.associating_id,
file_type=self.FileType.CONSENT_RECORD,
is_archived=False,
)
if self.pk:
other_files = other_files.exclude(pk=self.pk)
consent = PatientConsent.objects.get(external_id=self.associating_id)
patient_registration = consent.consultation.patient
patient_registration.has_consents = (
not self.is_archived or other_files.exists()
)
patient_registration.save()
return super().save(*args, **kwargs)

def __str__(self):
return f"{self.FileTypeChoices[self.file_type][1]} - {self.name}{' (Archived)' if self.is_archived else ''}"
4 changes: 4 additions & 0 deletions care/facility/models/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,10 @@ class TestTypeEnum(enum.Enum):
AbhaNumber, on_delete=models.SET_NULL, null=True, blank=True
)

has_consents = models.BooleanField(
shivankacker marked this conversation as resolved.
Show resolved Hide resolved
default=False, verbose_name="Patient has consent files"
)

history = HistoricalRecords(excluded_fields=["meta_info"])

objects = BaseManager()
Expand Down
Loading
Loading