19
19
from django .http import HttpResponseBadRequest , JsonResponse
20
20
from django .utils import timezone
21
21
from django .utils .crypto import get_random_string
22
+ from django .utils .translation import gettext_lazy as _
23
+ from django .conf import settings as django_settings
22
24
from django_auto_prefetching import prefetch
23
25
from django_filters .rest_framework import DjangoFilterBackend
24
26
from drf_excel .mixins import XLSXFileMixin
46
48
QueueStatistic ,
47
49
Semester ,
48
50
Tag ,
51
+ Booking ,
49
52
)
50
53
from ohq .pagination import QuestionSearchPagination
51
54
from ohq .permissions import (
63
66
QueuePermission ,
64
67
QueueStatisticPermission ,
65
68
TagPermission ,
69
+ BookingPermission ,
66
70
)
67
71
from ohq .schemas import EventSchema , MassInviteSchema , OccurrenceSchema
68
72
from ohq .serializers import (
81
85
SemesterSerializer ,
82
86
TagSerializer ,
83
87
UserPrivateSerializer ,
88
+ BookingSerializer ,
84
89
)
85
90
from ohq .sms import sendSMSVerification
86
91
@@ -741,15 +746,15 @@ class OccurrenceViewSet(
741
746
You must specify all of the fields or use a patch request.
742
747
743
748
partial_update:
744
- Update certain fields in the Occurrece .
749
+ Update certain fields in the Occurrence .
745
750
"""
746
751
747
752
serializer_class = OccurrenceSerializer
748
753
permission_classes = [OccurrencePermission | IsSuperuser ]
749
754
schema = OccurrenceSchema ()
750
755
751
756
def list (self , request , * args , ** kwargs ):
752
- # ensure timezone consitency
757
+ # ensure timezone consistency
753
758
course_ids = request .GET .getlist ("course" )
754
759
filter_start = datetime .strptime (
755
760
request .GET .get ("filter_start" ), "%Y-%m-%dT%H:%M:%SZ"
@@ -772,6 +777,103 @@ def list(self, request, *args, **kwargs):
772
777
773
778
serializer = OccurrenceSerializer (occurrences , many = True )
774
779
return JsonResponse (serializer .data , safe = False )
780
+
781
+ def update (self , request , * args , ** kwargs ):
782
+ occurrence = self .get_object ()
783
+ old_start = occurrence .start
784
+ old_end = occurrence .end
785
+ occurrence .start = datetime .strptime (request .data .get ("start" ), "%Y-%m-%dT%H:%M:%SZ" ).replace (
786
+ tzinfo = utc
787
+ )
788
+ occurrence .end = datetime .strptime (request .data .get ("end" ), "%Y-%m-%dT%H:%M:%SZ" ).replace (
789
+ tzinfo = utc
790
+ )
791
+ start_delta = occurrence .start - old_start
792
+ end_delta = occurrence .end - old_end
793
+ occurrence .save ()
794
+
795
+ bookings = Booking .objects .filter (occurrence = occurrence ).order_by ("start" )
796
+
797
+ for booking in bookings :
798
+ booking .start += start_delta
799
+ booking .end += end_delta
800
+ booking .save ()
801
+
802
+ serializer = OccurrenceSerializer (occurrence )
803
+ return JsonResponse (serializer .data , safe = False )
775
804
776
805
def get_queryset (self ):
777
806
return Occurrence .objects .filter (pk = self .kwargs ["pk" ])
807
+
808
+ class BookingViewSet (
809
+ mixins .ListModelMixin ,
810
+ mixins .RetrieveModelMixin ,
811
+ mixins .CreateModelMixin ,
812
+ mixins .UpdateModelMixin ,
813
+ viewsets .GenericViewSet ,
814
+ ):
815
+ """
816
+ retrieve:
817
+ Return a Booking.
818
+
819
+ list:
820
+ You should pass in an occurrence id, and all the bookings related to that occurrence will be returned to you.
821
+ Return a list of bookings.
822
+
823
+ create:
824
+ Create a booking.
825
+ occurrenceId is required in body.
826
+
827
+ update:
828
+ Update all fields in a Booking.
829
+ You must specify all of the fields or use a patch request.
830
+
831
+ partial_update:
832
+ Update certain fields in the Booking.
833
+ """
834
+
835
+ serializer_class = BookingSerializer
836
+ permission_classes = [BookingPermission | IsSuperuser ]
837
+
838
+ def create (self , request , * args , ** kwargs ):
839
+ occurrence_id = request .data .get ("occurrence" )
840
+ occurrence = Occurrence .objects .get (id = occurrence_id )
841
+ user = request .user
842
+ existing_bookings = Booking .objects .filter (occurrence = occurrence ).order_by ("start" )
843
+
844
+ if existing_bookings .exists ():
845
+ last_booking = existing_bookings .last ()
846
+ start = last_booking .end
847
+ else :
848
+ start = occurrence .start
849
+
850
+ end = start + occurrence .interval
851
+
852
+ if start < occurrence .start or end > occurrence .end :
853
+ raise ValidationError (_ ("Booking times must be within the occurrence's time range." ))
854
+
855
+ booking = Booking (
856
+ occurrence = occurrence ,
857
+ user = user ,
858
+ start = start ,
859
+ end = end ,
860
+ )
861
+
862
+ booking .save ()
863
+
864
+ serializer = BookingSerializer (booking )
865
+ return JsonResponse (serializer .data , safe = False )
866
+
867
+ def list (self ,request , * args , ** kwargs ):
868
+ occurrence_id = request .GET .get ("occurrence" )
869
+ if occurrence_id is None :
870
+ raise ValidationError (_ (f"Occurrence id is required." ))
871
+
872
+ occurrence = Occurrence .objects .get (id = occurrence_id )
873
+ existing_bookings = Booking .objects .filter (occurrence = occurrence ).order_by ("start" )
874
+
875
+ serializer = BookingSerializer (existing_bookings , many = True )
876
+ return JsonResponse (serializer .data , safe = False )
877
+
878
+ def get_queryset (self ):
879
+ return Booking .objects .filter (pk = self .kwargs ["pk" ])
0 commit comments