Skip to content

Commit

Permalink
fix(asset_location): added custom through model
Browse files Browse the repository at this point in the history
  • Loading branch information
aeswibon committed Nov 17, 2023
1 parent 4164c4c commit 5675971
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 73 deletions.
48 changes: 7 additions & 41 deletions care/facility/api/serializers/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from django.core.cache import cache
from django.db import transaction
from django.db.models import Q
from django.shortcuts import get_object_or_404
from django.utils.timezone import now
from rest_framework import serializers
Expand Down Expand Up @@ -33,7 +32,6 @@
UserAssignedSerializer,
UserBaseMinimumSerializer,
)
from care.users.models import User
from care.utils.assetintegration.hl7monitor import HL7MonitorAsset
from care.utils.assetintegration.onvif import OnvifAsset
from care.utils.assetintegration.ventilator import VentilatorAsset
Expand All @@ -45,12 +43,11 @@
class AssetLocationSerializer(ModelSerializer):
facility = FacilityBareMinimumSerializer(read_only=True)
id = UUIDField(source="external_id", read_only=True)
users = serializers.SerializerMethodField()

duty_staff_objects = UserAssignedSerializer(
many=True,
read_only=True,
source="duty_staff",
)
def get_users(self, obj):
users = obj.users.filter(assetlocationdutystaff__deleted=False)
return UserAssignedSerializer(users, many=True, read_only=True).data

def validate_middleware_address(self, value):
value = (value or "").strip()
Expand Down Expand Up @@ -87,39 +84,6 @@ class Meta:
read_only_fields = TIMESTAMP_FIELDS


class AssetLocationDutyStaffSerializer(ModelSerializer):
duty_staff_objects = UserAssignedSerializer(
many=True,
read_only=True,
source="duty_staff",
)

class Meta:
model = AssetLocation
fields = (
"duty_staff_objects",
"duty_staff",
)

def validate_duty_staff(self, value):
if not value:
raise ValidationError({"duty_staff": "Duty staff cannot be empty"})

duty_staff_ids = [user.id for user in value]
facility_id = self.instance.facility.id

count = User.objects.filter(
Q(home_facility__id=facility_id) & Q(id__in=duty_staff_ids)
).count()

if count != len(duty_staff_ids):
raise ValidationError(
{"duty_staff": "Only Home Facility Doctors and Staffs are allowed"}
)

return value


class AssetBareMinimumSerializer(ModelSerializer):
id = UUIDField(source="external_id", read_only=True)

Expand Down Expand Up @@ -241,7 +205,9 @@ def create(self, validated_data):
asset_instance = super().create(validated_data)
if last_serviced_on or note:
asset_service = AssetService(
asset=asset_instance, serviced_on=last_serviced_on, note=note
asset=asset_instance,
serviced_on=last_serviced_on,
note=note,
)
asset_service.save()
asset_instance.last_service = asset_service
Expand Down
41 changes: 29 additions & 12 deletions care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from django.core.cache import cache
from django.db import transaction
from django.db.models import Exists, OuterRef, Q
from django.db.models.signals import post_save
from django.dispatch import receiver
Expand Down Expand Up @@ -30,7 +31,6 @@

from care.facility.api.serializers.asset import (
AssetAvailabilitySerializer,
AssetLocationDutyStaffSerializer,
AssetLocationSerializer,
AssetSerializer,
AssetServiceSerializer,
Expand All @@ -43,6 +43,7 @@
Asset,
AssetAvailabilityRecord,
AssetLocation,
AssetLocationDutyStaff,
AssetService,
AssetTransaction,
ConsultationBedAsset,
Expand Down Expand Up @@ -87,11 +88,6 @@ class AssetLocationViewSet(
filter_backends = (drf_filters.SearchFilter,)
search_fields = ["name"]

def get_serializer_class(self):
if self.action == "duty_staff":
return AssetLocationDutyStaffSerializer
return super().get_serializer_class()

def get_serializer_context(self):
facility = self.get_facility()
context = super().get_serializer_context()
Expand Down Expand Up @@ -131,14 +127,35 @@ def duty_staff(self, request, facility_external_id, external_id):
Endpoint for assigning staffs to asset location
"""

asset = self.get_object()
serializer = AssetLocationDutyStaffSerializer(asset, data=request.data)
serializer.is_valid(raise_exception=True)
asset: AssetLocation = self.get_object()
duty_staff = request.data.get("duty_staff", [])

count = User.objects.filter(
Q(home_facility=asset.facility) & Q(id__in=duty_staff)
).count()

if count != len(duty_staff):
raise ValidationError(
{"duty_staff": "Only Home Facility Doctors ayynd Staffs are allowed"}
)

AssetLocationDutyStaff.objects.filter(asset_location=asset).update(deleted=True)

users = User.objects.filter(id__in=duty_staff)
with transaction.atomic():
duty_staff_objects = []
for user in users:
duty_staff_objects.append(
AssetLocationDutyStaff(
asset_location=asset,
user=user,
created_by=request.user,
)
)

staffs = serializer.validated_data["duty_staff"]
asset.duty_staff.set(staffs)
AssetLocationDutyStaff.objects.bulk_create(duty_staff_objects)

return Response(self.get_serializer(asset).data)
return Response(status=status.HTTP_201_CREATED)


class AssetFilter(filters.FilterSet):
Expand Down
19 changes: 0 additions & 19 deletions care/facility/migrations/0393_assetlocation_duty_staff.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Generated by Django 4.2.5 on 2023-11-17 06:36

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("facility", "0392_alter_dailyround_consciousness_level"),
]

operations = [
migrations.CreateModel(
name="AssetLocationDutyStaff",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("deleted", models.BooleanField(default=False)),
(
"asset_location",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="facility.assetlocation",
),
),
(
"created_by",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="assigned_duty_staff",
to=settings.AUTH_USER_MODEL,
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.AddField(
model_name="assetlocation",
name="users",
field=models.ManyToManyField(
blank=True,
related_name="duty_staff",
through="facility.AssetLocationDutyStaff",
to=settings.AUTH_USER_MODEL,
),
),
]
31 changes: 30 additions & 1 deletion care/facility/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ class RoomType(enum.Enum):
Facility, on_delete=models.PROTECT, null=False, blank=False
)

duty_staff = models.ManyToManyField(
users = models.ManyToManyField(
User,
through="AssetLocationDutyStaff",
related_name="duty_staff",
through_fields=("asset_location", "user"),
blank=True,
)

Expand All @@ -56,6 +59,32 @@ class RoomType(enum.Enum):
)


class AssetLocationDutyStaff(models.Model):
asset_location = models.ForeignKey(
AssetLocation, on_delete=models.CASCADE, null=False, blank=False
)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)

deleted = models.BooleanField(default=False)

created_by = models.ForeignKey(
User,
on_delete=models.PROTECT,
null=False,
blank=False,
related_name="assigned_duty_staff",
)

def __str__(self):
return f"{self.user} under {self.asset_location.name}"

CSV_MAPPING = {
"asset_location__name": "Asset Location Name",
"user__username": "User",
"created_by__username": "Assigned By",
}


class AssetType(enum.Enum):
INTERNAL = 50
EXTERNAL = 100
Expand Down

0 comments on commit 5675971

Please sign in to comment.