Skip to content

Commit

Permalink
Merge pull request #2738 from ohcnetwork/rithviknishad/feat/reschedule
Browse files Browse the repository at this point in the history
Add Reschedule API and serialize Facility in TokenBooking
  • Loading branch information
vigneshhari authored Jan 16, 2025
2 parents 730479d + 0a17156 commit 85fb587
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
43 changes: 41 additions & 2 deletions care/emr/api/viewsets/scheduling/booking.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.db import transaction
from django_filters import CharFilter, DateFromToRangeFilter, FilterSet, UUIDFilter
from django_filters.rest_framework import DjangoFilterBackend
from pydantic import BaseModel
from pydantic import UUID4, BaseModel
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import get_object_or_404
Expand All @@ -15,6 +15,8 @@
EMRRetrieveMixin,
EMRUpdateMixin,
)
from care.emr.api.viewsets.scheduling import lock_create_appointment
from care.emr.models import TokenSlot
from care.emr.models.scheduling import SchedulableUserResource, TokenBooking
from care.emr.resources.scheduling.slot.spec import (
CANCELLED_STATUS_CHOICES,
Expand All @@ -29,10 +31,16 @@

class CancelBookingSpec(BaseModel):
reason: Literal[
BookingStatusChoices.cancelled, BookingStatusChoices.entered_in_error
BookingStatusChoices.cancelled,
BookingStatusChoices.entered_in_error,
BookingStatusChoices.rescheduled,
]


class RescheduleBookingSpec(BaseModel):
new_slot: UUID4


class TokenBookingFilters(FilterSet):
status = CharFilter(field_name="status")
date = DateFromToRangeFilter(field_name="token_slot__start_datetime__date")
Expand Down Expand Up @@ -117,6 +125,37 @@ def cancel(self, request, *args, **kwargs):
self.authorize_update({}, instance)
return self.cancel_appointment_handler(instance, request.data, request.user)

@action(detail=True, methods=["POST"])
def reschedule(self, request, *args, **kwargs):
request_data = RescheduleBookingSpec(**request.data)
existing_booking = self.get_object()
facility = self.get_facility_obj()
self.authorize_update({}, existing_booking)
if not AuthorizationController.call(
"can_create_appointment", self.request.user, facility
):
raise PermissionDenied("You do not have permission to create appointments")
new_slot = get_object_or_404(
TokenSlot,
external_id=request_data.new_slot,
resource=existing_booking.token_slot.resource,
)
with transaction.atomic():
self.cancel_appointment_handler(
existing_booking,
{"reason": BookingStatusChoices.rescheduled},
request.user,
)
appointment = lock_create_appointment(
new_slot,
existing_booking.patient,
request.user,
existing_booking.reason_for_visit,
)
return Response(
TokenBookingReadSpec.serialize(appointment).model_dump(exclude=["meta"])
)

@action(detail=False, methods=["GET"])
def available_users(self, request, *args, **kwargs):
facility = Facility.objects.get(external_id=self.kwargs["facility_external_id"])
Expand Down
8 changes: 8 additions & 0 deletions care/emr/resources/scheduling/slot/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
from care.emr.models.scheduling.booking import TokenSlot
from care.emr.models.scheduling.schedule import Availability
from care.emr.resources.base import EMRResource
from care.emr.resources.facility.spec import FacilityBareMinimumSpec
from care.emr.resources.patient.otp_based_flow import PatientOTPReadSpec
from care.emr.resources.user.spec import UserSpec
from care.facility.models import Facility
from care.users.models import User


Expand Down Expand Up @@ -52,11 +54,13 @@ class BookingStatusChoices(str, Enum):
checked_in = "checked_in"
waitlist = "waitlist"
in_consultation = "in_consultation"
rescheduled = "rescheduled"


CANCELLED_STATUS_CHOICES = [
BookingStatusChoices.entered_in_error.value,
BookingStatusChoices.cancelled.value,
BookingStatusChoices.rescheduled.value,
]


Expand All @@ -83,6 +87,7 @@ class TokenBookingReadSpec(TokenBookingBaseSpec):
status: str
reason_for_visit: str
user: dict = {}
facility: dict = {}

@classmethod
def perform_extra_serialization(cls, mapping, obj):
Expand All @@ -96,3 +101,6 @@ def perform_extra_serialization(cls, mapping, obj):
mapping["user"] = UserSpec.serialize(
User.objects.get(id=obj.token_slot.resource.user_id)
).model_dump(exclude=["meta"])
mapping["facility"] = FacilityBareMinimumSpec.serialize(
Facility.objects.get(id=obj.token_slot.resource.facility_id)
).model_dump(exclude=["meta"])

0 comments on commit 85fb587

Please sign in to comment.