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

Improved asset bed relations for camera preset #2387

Merged
merged 24 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ce02ab6
Adds camera preset model
rithviknishad May 30, 2024
9be89c9
Migration to backfill and soft delete duplicate asset bed records
rithviknishad May 30, 2024
78750d0
Delete assed bed records that has no asset class
rithviknishad May 30, 2024
fc04420
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Jul 5, 2024
ae7dfee
rebase migrations
rithviknishad Jul 5, 2024
acd2c8e
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Jul 9, 2024
0560415
stash
rithviknishad Jul 23, 2024
e296e21
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Aug 22, 2024
6da45bf
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Aug 30, 2024
e5041ce
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Sep 19, 2024
0a199fb
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Sep 20, 2024
d5b24ec
rebase migrations
rithviknishad Sep 20, 2024
b27b7e9
Merge branch 'develop' into rithviknishad/feat/camera-presets
sainak Sep 25, 2024
a90848f
Merge branch 'develop' into rithviknishad/feat/camera-presets
rithviknishad Sep 26, 2024
aee281a
rebase migrations and fix issues
rithviknishad Sep 29, 2024
a971edd
fix accidentally creating preset in update preset
rithviknishad Oct 3, 2024
a49350d
remove boundary preset support
rithviknishad Oct 7, 2024
2375ecd
optimize preset name valdiation check
rithviknishad Oct 8, 2024
8042a7f
refactor viewsets
rithviknishad Oct 8, 2024
55b9eb8
Merge branch 'develop' into rithviknishad/feat/camera-presets
nihal467 Oct 11, 2024
3aa52e8
make asset, bed, assetbed get_queryset reusable based on user
rithviknishad Oct 15, 2024
a6049ff
prevent accidentally attempting to evaluate queryset early
rithviknishad Oct 15, 2024
fc41114
Merge remote-tracking branch 'origin' into rithviknishad/feat/camera-…
rithviknishad Oct 16, 2024
1370725
migration: skip purging data, handle exceptions; add tests
rithviknishad Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions care/facility/api/serializers/bed.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,14 @@ def validate(self, attrs):
{"asset": "Should be in the same facility as the bed"}
)
if (
asset.asset_class == AssetClasses.HL7MONITOR.name
and AssetBed.objects.filter(
bed=bed, asset__asset_class=asset.asset_class
).exists()
):
asset.asset_class
in [
AssetClasses.HL7MONITOR.name,
AssetClasses.ONVIF.name,
]
) and AssetBed.objects.filter(
bed=bed, asset__asset_class=asset.asset_class
).exists():
raise ValidationError(
{
"asset": "Bed is already in use by another asset of the same class"
Expand Down
49 changes: 49 additions & 0 deletions care/facility/api/serializers/camera_preset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from care.facility.api.serializers.bed import AssetBedSerializer
from care.facility.models import CameraPreset
from care.users.api.serializers.user import UserBaseMinimumSerializer


class CameraPresetSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="external_id", read_only=True)
created_by = UserBaseMinimumSerializer(read_only=True)
updated_by = UserBaseMinimumSerializer(read_only=True)
asset_bed = AssetBedSerializer(read_only=True)

class Meta:
model = CameraPreset
exclude = (
"external_id",
"deleted",
)
read_only_fields = (
"created_date",
"modified_date",
"is_migrated",
"created_by",
"updated_by",
)

def get_asset_bed_obj(self):
return (
self.instance.asset_bed if self.instance else self.context.get("asset_bed")
)

def validate_name(self, value):
if CameraPreset.objects.filter(
asset_bed__bed_id=self.get_asset_bed_obj().bed_id, name=value
).exists():
msg = "Name should be unique. Another preset related to this bed already uses the same name."
raise ValidationError(msg)
return value

def create(self, validated_data):
validated_data["created_by"] = self.context["request"].user
validated_data["asset_bed"] = self.get_asset_bed_obj()
return super().create(validated_data)

def update(self, instance, validated_data):
validated_data["updated_by"] = self.context["request"].user
return super().update(instance, validated_data)
17 changes: 2 additions & 15 deletions care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
from care.utils.assetintegration.asset_classes import AssetClasses
from care.utils.cache.cache_allowed_facilities import get_accessible_facilities
from care.utils.filters.choicefilter import CareChoiceFilter, inverse_choices
from care.utils.queryset.asset_bed import get_asset_queryset
from care.utils.queryset.asset_location import get_asset_location_queryset
from care.utils.queryset.facility import get_facility_queryset
from config.authentication import MiddlewareAuthentication
Expand Down Expand Up @@ -290,21 +291,7 @@ class AssetViewSet(
filterset_class = AssetFilter

def get_queryset(self):
user = self.request.user
queryset = self.queryset
if user.is_superuser:
pass
elif user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]:
queryset = queryset.filter(current_location__facility__state=user.state)
elif user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]:
queryset = queryset.filter(
current_location__facility__district=user.district
)
else:
allowed_facilities = get_accessible_facilities(user)
queryset = queryset.filter(
current_location__facility__id__in=allowed_facilities
)
queryset = get_asset_queryset(user=self.request.user, queryset=self.queryset)
return queryset.annotate(
latest_status=Subquery(
AvailabilityRecord.objects.filter(
Expand Down
48 changes: 7 additions & 41 deletions care/facility/api/viewsets/bed.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from care.users.models import User
from care.utils.cache.cache_allowed_facilities import get_accessible_facilities
from care.utils.filters.choicefilter import CareChoiceFilter, inverse_choices
from care.utils.queryset.asset_bed import get_asset_bed_queryset, get_bed_queryset

inverse_bed_type = inverse_choices(BedTypeChoices)

Expand Down Expand Up @@ -76,27 +77,14 @@ class BedViewSet(
filterset_class = BedFilter

def get_queryset(self):
user = self.request.user
queryset = self.queryset

queryset = queryset.annotate(
queryset = self.queryset.annotate(
is_occupied=Exists(
ConsultationBed.objects.filter(
bed__id=OuterRef("id"), end_date__isnull=True
)
)
)

if user.is_superuser:
pass
elif user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]:
queryset = queryset.filter(facility__state=user.state)
elif user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]:
queryset = queryset.filter(facility__district=user.district)
else:
allowed_facilities = get_accessible_facilities(user)
queryset = queryset.filter(facility__id__in=allowed_facilities)
return queryset
return get_bed_queryset(user=self.request.user, queryset=queryset)

@transaction.atomic
def create(self, request, *args, **kwargs):
Expand Down Expand Up @@ -168,18 +156,7 @@ class AssetBedViewSet(
lookup_field = "external_id"

def get_queryset(self):
user = self.request.user
queryset = self.queryset
if user.is_superuser:
pass
elif user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]:
queryset = queryset.filter(bed__facility__state=user.state)
elif user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]:
queryset = queryset.filter(bed__facility__district=user.district)
else:
allowed_facilities = get_accessible_facilities(user)
queryset = queryset.filter(bed__facility__id__in=allowed_facilities)
return queryset
return get_asset_bed_queryset(user=self.request.user, queryset=self.queryset)


class PatientAssetBedFilter(filters.FilterSet):
Expand Down Expand Up @@ -212,20 +189,9 @@ class PatientAssetBedViewSet(ListModelMixin, GenericViewSet):
]

def get_queryset(self):
user = self.request.user
queryset = self.queryset
if user.is_superuser:
pass
elif user.user_type >= User.TYPE_VALUE_MAP["StateLabAdmin"]:
queryset = queryset.filter(bed__facility__state=user.state)
elif user.user_type >= User.TYPE_VALUE_MAP["DistrictLabAdmin"]:
queryset = queryset.filter(bed__facility__district=user.district)
else:
allowed_facilities = get_accessible_facilities(user)
queryset = queryset.filter(bed__facility__id__in=allowed_facilities)
return queryset.filter(
bed__facility__external_id=self.kwargs["facility_external_id"]
)
return get_asset_bed_queryset(
user=self.request.user, queryset=self.queryset
).filter(bed__facility__external_id=self.kwargs["facility_external_id"])


class ConsultationBedFilter(filters.FilterSet):
Expand Down
63 changes: 63 additions & 0 deletions care/facility/api/viewsets/camera_preset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from django.shortcuts import get_object_or_404
from rest_framework.exceptions import NotFound
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet, ModelViewSet

from care.facility.api.serializers.camera_preset import CameraPresetSerializer
from care.facility.models import CameraPreset
from care.utils.queryset.asset_bed import (
get_asset_bed_queryset,
get_asset_queryset,
get_bed_queryset,
)


class AssetBedCameraPresetViewSet(ModelViewSet):
serializer_class = CameraPresetSerializer
queryset = CameraPreset.objects.all().select_related(
"asset_bed", "created_by", "updated_by"
)
lookup_field = "external_id"
permission_classes = (IsAuthenticated,)

def get_asset_bed_obj(self):
queryset = get_asset_bed_queryset(self.request.user).filter(
external_id=self.kwargs["assetbed_external_id"]
)
return get_object_or_404(queryset)

def get_queryset(self):
return super().get_queryset().filter(asset_bed=self.get_asset_bed_obj())

def get_serializer_context(self):
context = super().get_serializer_context()
context["asset_bed"] = self.get_asset_bed_obj()
return context


class CameraPresetViewSet(GenericViewSet, ListModelMixin):
rithviknishad marked this conversation as resolved.
Show resolved Hide resolved
serializer_class = CameraPresetSerializer
queryset = CameraPreset.objects.all().select_related(
"asset_bed", "created_by", "updated_by"
)
lookup_field = "external_id"
permission_classes = (IsAuthenticated,)

def get_bed_obj(self, external_id: str):
queryset = get_bed_queryset(self.request.user).filter(external_id=external_id)
return get_object_or_404(queryset)

def get_asset_obj(self, external_id: str):
queryset = get_asset_queryset(self.request.user).filter(external_id=external_id)
return get_object_or_404(queryset)

def get_queryset(self):
queryset = super().get_queryset()
if asset_external_id := self.kwargs.get("asset_external_id"):
return queryset.filter(
asset_bed__asset=self.get_asset_obj(asset_external_id)
)
if bed_external_id := self.kwargs.get("bed_external_id"):
return queryset.filter(asset_bed__bed=self.get_bed_obj(bed_external_id))
raise NotFound
Loading
Loading