Fakultas Ilmu Komputer UI

Commit 0a57d7ee authored by Jonathan Christopher Jakub's avatar Jonathan Christopher Jakub
Browse files

[RED] Implement reworked monitoring case

parent 803449bf
......@@ -9,15 +9,16 @@ CASE_SUBJECT_FILTERSET_FIELDS = (
"address",
"district",
"sub_district",
"author__name",
"created_at",
)
CASE_SUBJECT_SEARCH_FIELDS = (
"name",
"age",
"address",
"district",
"sub_district",
"created_at",
"author__name",
)
CASE_SUBJECT_ORDERING_FIELDS = (
......@@ -27,6 +28,7 @@ CASE_SUBJECT_ORDERING_FIELDS = (
"address",
"district",
"sub_district",
"author__name",
"created_at",
)
......@@ -49,6 +51,8 @@ INVESTIGATION_CASE_FILTERSET_FIELDS = (
"is_referral_needed",
"medical_facility_reference",
"outcome",
"author__name",
"created_at",
)
INVESTIGATION_CASE_SEARCH_FIELDS = (
......@@ -69,7 +73,7 @@ INVESTIGATION_CASE_SEARCH_FIELDS = (
"risk_factors",
"medical_facility_reference",
"outcome",
"created_at",
"author__name",
)
INVESTIGATION_CASE_ORDERING_FIELDS = (
......@@ -93,19 +97,37 @@ INVESTIGATION_CASE_ORDERING_FIELDS = (
"is_referral_needed",
"medical_facility_reference",
"outcome",
"author__name",
"created_at",
)
MONITORING_CASE_FILTERSET_FIELDS = (
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"author__name",
"created_at",
)
MONITORING_CASE_SEARCH_FIELDS = (
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"author__name",
)
MONITORING_CASE_ORDERING_FIELDS = (
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"author__name",
"created_at",
)
class MonitoringCaseFilter(FilterSet):
class Meta:
model = MonitoringCase
fields = (
"investigation_case_id",
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"author",
)
\ No newline at end of file
# Generated by Django 3.0.1 on 2020-04-19 09:56
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_auto_20200419_0156'),
('cases', '0007_auto_20200418_1632'),
]
operations = [
migrations.RenameField(
model_name='monitoringcase',
old_name='revision_id',
new_name='id',
),
migrations.RemoveField(
model_name='monitoringcase',
name='case_id',
),
migrations.RemoveField(
model_name='monitoringcase',
name='investigation_case_id',
),
migrations.RemoveField(
model_name='monitoringcase',
name='is_active',
),
migrations.AddField(
model_name='monitoringcase',
name='investigation_case',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='monitoring_case', to='cases.InvestigationCase'),
),
migrations.AlterField(
model_name='investigationcase',
name='reference_case',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='investigation_case', to='cases.InvestigationCase'),
),
migrations.CreateModel(
name='MonitoringCaseHistory',
fields=[
('revision_id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('object_id', models.UUIDField(default=uuid.uuid4, editable=False)),
('action_type', models.CharField(choices=[('Create', 'Create'), ('Edit', 'Edit'), ('Delete', 'Delete')], max_length=64)),
('recorded_at', models.DateTimeField(auto_now_add=True)),
('investigation_case_id', models.UUIDField(blank=True, null=True)),
('is_referred', models.BooleanField(blank=True, db_index=True, null=True)),
('is_checked', models.BooleanField(blank=True, db_index=True, null=True)),
('regular_medicine_intake', models.TextField(default='[]')),
('treatment_start_date', models.DateField(blank=True, null=True)),
('treatment_end_date', models.DateField(blank=True, null=True)),
('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='monitoring_case_history', to='accounts.Account')),
],
options={
'abstract': False,
},
),
]
......@@ -5,8 +5,8 @@ from django.core.exceptions import ValidationError
from django.db import models
from apps.accounts.models import Account
from apps.commons.managers import SoftObjectManager, SoftDeleteManager
from apps.commons.models import HistoryEnabledModel
from apps.commons.managers import SoftDeleteManager
from apps.commons.models import HistoryEnabledModel, HistoryModel
from apps.constants import (
TIMEZONE,
ACTIVITY_TYPE_CHOICES,
......@@ -16,11 +16,7 @@ from apps.constants import (
)
class CaseSubjectHistory(models.Model):
revision_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
object_id = models.UUIDField(default=uuid.uuid4, editable=False)
action_type = models.CharField(choices=ACTIVITY_TYPE_CHOICES, max_length=64)
recorded_at = models.DateTimeField(auto_now_add=True)
class CaseSubjectHistory(HistoryModel):
name = models.CharField(max_length=128)
age = models.IntegerField()
is_male = models.BooleanField(db_index=True)
......@@ -41,10 +37,7 @@ class CaseSubjectHistory(models.Model):
ordering = ["-recorded_at"]
def __str__(self):
return (
f"[History] Rev. {self.revision_id} - {self.name} | "
+ f"{self.district}, {self.sub_district}"
)
return f"[History] {self.revision_id} | {self.object_id}"
class CaseSubject(HistoryEnabledModel):
......@@ -72,16 +65,12 @@ class CaseSubject(HistoryEnabledModel):
def __str__(self):
return (
f"[Active] ID. {self.id} - {self.name} | "
f"ID. {self.id} - {self.name} | "
+ f"{self.district}, {self.sub_district}"
)
class InvestigationCaseHistory(models.Model):
revision_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
object_id = models.UUIDField(default=uuid.uuid4, editable=False)
action_type = models.CharField(choices=ACTIVITY_TYPE_CHOICES, max_length=64)
recorded_at = models.DateTimeField(auto_now_add=True)
class InvestigationCaseHistory(HistoryModel):
case_subject_id = models.UUIDField(blank=True, null=True)
reference_case_id = models.UUIDField(blank=True, null=True)
case_relation = models.CharField(max_length=128, blank=True)
......@@ -104,7 +93,7 @@ class InvestigationCaseHistory(models.Model):
ordering = ["-recorded_at"]
def __str__(self):
return f"[Active] Rev. {self.revision_id} | by {self.author}"
return f"[History] {self.revision_id} | {self.object_id}"
@property
def reference_case(self):
......@@ -132,7 +121,7 @@ class InvestigationCase(HistoryEnabledModel):
blank=True,
null=True,
on_delete=models.DO_NOTHING,
related_name="referring_investigation_case",
related_name="investigation_case",
)
case_relation = models.CharField(max_length=128, blank=True)
medical_symptoms = models.TextField(default="{}")
......@@ -159,18 +148,47 @@ class InvestigationCase(HistoryEnabledModel):
ordering = ["-created_at"]
def __str__(self):
return f"[Active] ID. {self.id} | by {self.author}"
return f"ID. {self.id} | by {self.author}"
class MonitoringCase(models.Model):
revision_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
case_id = models.UUIDField(default=uuid.uuid4, editable=False)
class MonitoringCaseHistory(HistoryModel):
investigation_case_id = models.UUIDField(blank=True, null=True)
is_referred = models.BooleanField(blank=True, null=True, db_index=True)
is_checked = models.BooleanField(blank=True, null=True, db_index=True)
regular_medicine_intake = models.TextField(default="[]")
treatment_start_date = models.DateField(blank=True, null=True)
treatment_end_date = models.DateField(blank=True, null=True)
author = models.ForeignKey(
Account,
blank=True,
null=True,
on_delete=models.DO_NOTHING,
related_name="monitoring_case_history",
)
def __str__(self):
return f"[History] {self.revision_id} | {self.object_id}"
@property
def investigation_case(self):
return InvestigationCase.objects.filter(
deleted_at__isnull=True, id=self.investigation_case_id
).first()
class MonitoringCase(HistoryEnabledModel):
investigation_case = models.ForeignKey(
InvestigationCase,
blank=True,
null=True,
on_delete=models.DO_NOTHING,
related_name="monitoring_case",
)
is_referred = models.BooleanField(blank=True, null=True, db_index=True)
is_checked = models.BooleanField(blank=True, null=True, db_index=True)
regular_medicine_intake = models.TextField(default="[]")
treatment_start_date = models.DateField(blank=True, null=True)
treatment_end_date = models.DateField(blank=True, null=True)
author = models.ForeignKey(
Account,
blank=True,
......@@ -178,11 +196,11 @@ class MonitoringCase(models.Model):
on_delete=models.DO_NOTHING,
related_name="monitoring_case",
)
deleted_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True, db_index=True)
objects = SoftObjectManager()
history_class = MonitoringCaseHistory
relation_fields = ["investigation_case"]
objects = SoftDeleteManager()
class Meta:
db_table = "monitoring_case"
......@@ -190,25 +208,4 @@ class MonitoringCase(models.Model):
ordering = ["-created_at"]
def __str__(self):
if self.is_active:
return f"[Active] Rev. {self.revision_id} | by {self.author}"
return f"[Inactive] Rev. {self.revision_id} | by {self.author}"
def save(self, *args, **kwargs):
self.clean()
return super(MonitoringCase, self).save(*args, **kwargs)
def clean(self):
super(MonitoringCase, self).clean()
def delete(self):
if self.deleted_at is None:
self.is_active = False
self.deleted_at = datetime.now(tz=pytz.timezone(TIMEZONE))
self.save()
@property
def investigation_case(self):
return InvestigationCase.objects.filter(
is_active=True, deleted_at__isnull=True, case_id=self.investigation_case_id
).first()
return f"ID. {self.id} | by {self.author}"
......@@ -11,7 +11,6 @@ from apps.cases.models import (
class CaseSubjectSerializer(serializers.ModelSerializer):
class Meta:
model = CaseSubject
fields = [
......@@ -25,6 +24,10 @@ class CaseSubjectSerializer(serializers.ModelSerializer):
"created_at",
]
def save(self):
account = self.context.get('request').user.account
super(CaseSubjectSerializer, self).save(author=account)
class CaseSubjectHistorySerializer(serializers.ModelSerializer):
......@@ -82,51 +85,52 @@ class InvestigationCaseSerializer(serializers.ModelSerializer):
"outcome",
]
def save(self):
account = self.context.get('request').user.account
super(InvestigationCaseSerializer, self).save(author=account)
def to_representation(self, instance):
serializer = InvestigationCaseSummarySerializer(instance)
return serializer.data
class MonitoringCaseSerializer(serializers.ModelSerializer):
is_active = serializers.BooleanField(read_only=True)
class MonitoringCaseSummarySerializer(serializers.ModelSerializer):
investigation_case = InvestigationCaseSummarySerializer()
author = AccountSerializer()
class Meta:
model = MonitoringCase
fields = [
"revision_id",
"case_id",
"investigation_case_id",
"id",
"investigation_case",
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"is_active",
"author",
]
class MonitoringCaseSummarySerializer(serializers.ModelSerializer):
investigation_case = serializers.SerializerMethodField()
is_active = serializers.BooleanField(read_only=True)
author = AccountSerializer()
class MonitoringCaseSerializer(serializers.ModelSerializer):
class Meta:
model = MonitoringCase
fields = [
"revision_id",
"case_id",
"investigation_case_id",
"id",
"investigation_case",
"is_referred",
"is_checked",
"regular_medicine_intake",
"treatment_start_date",
"treatment_end_date",
"author",
"is_active",
]
def get_investigation_case(self, instance):
investigation_case = instance.investigation_case
if investigation_case:
return InvestigationCaseSerializer(investigation_case).data
def save(self):
account = self.context.get('request').user.account
super(MonitoringCaseSerializer, self).save(author=account)
def to_representation(self, instance):
serializer = MonitoringCaseSummarySerializer(instance)
return serializer.data
import pytz
from datetime import datetime
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.db.models import Q
from rest_framework import status, viewsets
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView
......@@ -31,10 +27,11 @@ from apps.cases.filters import (
INVESTIGATION_CASE_FILTERSET_FIELDS,
INVESTIGATION_CASE_SEARCH_FIELDS,
INVESTIGATION_CASE_ORDERING_FIELDS,
MonitoringCaseFilter,
MONITORING_CASE_FILTERSET_FIELDS,
MONITORING_CASE_ORDERING_FIELDS,
MONITORING_CASE_SEARCH_FIELDS
)
from apps.commons.permissions import IsAuthorOrAdministrator
from apps.logs.models import Log
from apps.commons.permissions import IsAuthenticated
from apps.constants import (
MODEL_NAME_CASE_SUBJECT,
MODEL_NAME_INVESTIGATION_CASE,
......@@ -50,17 +47,20 @@ class CaseSubjectViewSet(viewsets.ModelViewSet):
queryset = CaseSubject.objects.all()
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filterset_fields = CASE_SUBJECT_FILTERSET_FIELDS
permission_classes = (IsAuthorOrAdministrator,)
permission_classes = (IsAuthenticated,)
pagination_class = PageNumberPagination
search_fields = CASE_SUBJECT_SEARCH_FIELDS
ordering_fields = CASE_SUBJECT_ORDERING_FIELDS
def perform_destroy(self, instance):
instance.delete(author=self.request.user.account)
class InvestigationCaseViewSet(viewsets.ModelViewSet):
serializer_class = InvestigationCaseSummarySerializer
queryset = InvestigationCase.objects.all()
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
permission_classes = (IsAuthorOrAdministrator,)
permission_classes = (IsAuthenticated,)
pagination_class = PageNumberPagination
filterset_fields = INVESTIGATION_CASE_FILTERSET_FIELDS
search_fields = INVESTIGATION_CASE_SEARCH_FIELDS
......@@ -75,97 +75,37 @@ class InvestigationCaseViewSet(viewsets.ModelViewSet):
if self.action in ['create', 'update']:
return InvestigationCaseSerializer
return InvestigationCaseSummarySerializer
def perform_destroy(self, instance):
instance.delete(author=self.request.user.account)
class InvestigationPositiveCaseAPIView(ListAPIView):
serializer_class = InvestigationCaseSummarySerializer
queryset = InvestigationCase.objects.all().filter(
queryset = InvestigationCase.objects.filter(
outcome__isnull=False).exclude(outcome__icontains="-")
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
permission_classes = (IsAuthorOrAdministrator,)
permission_classes = (IsAuthenticated,)
pagination_class = PageNumberPagination
filterset_fields = INVESTIGATION_CASE_FILTERSET_FIELDS
search_fields = INVESTIGATION_CASE_SEARCH_FIELDS
ordering_fields = INVESTIGATION_CASE_ORDERING_FIELDS
class MonitoringCaseViewSet(viewsets.ViewSet):
queryset = MonitoringCase.objects.active_revisions()
filter_backends = (DjangoFilterBackend,)
permission_classes = [
IsAuthorOrAdministrator,
]
def list(self, request):
paginator = PageNumberPagination()
filtered_set = MonitoringCaseFilter(request.GET, queryset=self.queryset).qs
context = paginator.paginate_queryset(filtered_set, request)
serializer = MonitoringCaseSummarySerializer(context, many=True)
return paginator.get_paginated_response(serializer.data)
def retrieve(self, request, pk=None):
instance = get_object_or_404(self.queryset, pk=pk)
serializer = MonitoringCaseSummarySerializer(instance)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request):
serializer = MonitoringCaseSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer_data = serializer.data
instance = MonitoringCase.objects.create(
**serializer_data, author=request.user.account
)
# Add monitoring case creation log
Log.objects.create(
model_name=MODEL_NAME_MONITORING_CASE,
object_id=instance.case_id,
revision_id=instance.revision_id,
action_type=ACTIVITY_TYPE_CREATE,
author=request.user.account,
)
return Response(
MonitoringCaseSummarySerializer(instance).data,
status=status.HTTP_201_CREATED,
)
def update(self, request, pk=None):
previous_instance = get_object_or_404(self.queryset, pk=pk)
serializer = MonitoringCaseSerializer(previous_instance, data=request.data)
serializer.is_valid(raise_exception=True)
serializer_data = serializer.validated_data
serializer_data["case_id"] = previous_instance.case_id
new_instance = MonitoringCase.objects.create(**serializer_data, is_active=True,)
previous_instance.is_active = False
previous_instance.save()
# Add monitoring case update log
Log.objects.create(
model_name=MODEL_NAME_MONITORING_CASE,
object_id=previous_instance.case_id,
revision_id=previous_instance.revision_id,
action_type=ACTIVITY_TYPE_EDIT,
author=request.user.account,
)
update_serializer = MonitoringCaseSummarySerializer(instance=new_instance)
return Response(update_serializer.data, status=status.HTTP_200_OK)
def destroy(self, request, pk=None):
instance = get_object_or_404(self.queryset, pk=pk)
instance.delete()
serializer = MonitoringCaseSummarySerializer(instance=instance)
class MonitoringCaseViewSet(viewsets.ModelViewSet):
serializer_class = MonitoringCaseSerializer
queryset = MonitoringCase.objects.all()
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
permission_classes = (IsAuthenticated,)
pagination_class = PageNumberPagination
filterset_fields = MONITORING_CASE_FILTERSET_FIELDS
search_fields = MONITORING_CASE_SEARCH_FIELDS
ordering_fields = MONITORING_CASE_ORDERING_FIELDS
# Add monitoring case deletion log
Log.objects.create(
model_name=MODEL_NAME_MONITORING_CASE,
object_id=instance.case_id,
revision_id=instance.revision_id,
action_type=ACTIVITY_TYPE_DELETE,
author=request.user.account,
)
def get_serializer_class(self):
if self.action in ['create', 'update']:
return MonitoringCaseSerializer
return MonitoringCaseSummarySerializer
return Response(serializer.data, status=status.HTTP_200_OK)
def perform_destroy(self, instance):
instance.delete(author=self.request.user.account)
......@@ -27,8 +27,11 @@ class SoftDeleteModel(BaseModel):
class Meta:
abstract = True
def delete(self):
def delete(self, *args, **kwargs):
author = kwargs.pop("author")
if self.deleted_at is None:
self.author = author
self.deleted_at = datetime.now(tz=pytz.timezone(TIMEZONE))
super(SoftDeleteModel, self).save()
return self
......@@ -66,21 +69,17 @@ class HistoryEnabledModel(SoftDeleteModel):
instance_dict["object_id"] = self.id
instance_dict["action_type"] = action
if hasattr(self, "author"):
self.history_class.objects.create(**instance_dict, author=author)
if self.history_class._meta.get_field("author").get_internal_type() == "UUIDField":
author_id = None if author is None else author.id
self.history_class.objects.create(**instance_dict, author=author_id)
else:
self.history_class.objects.create(**instance_dict)
self.history_class.objects.create(**instance_dict, author=author)
def save(self, *args, **kwargs):
if hasattr(self, "author"):
a