diff --git a/iridisite/__pycache__/settings.cpython-312.pyc b/iridisite/__pycache__/settings.cpython-312.pyc index be4c2c4..e59721b 100644 Binary files a/iridisite/__pycache__/settings.cpython-312.pyc and b/iridisite/__pycache__/settings.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/admin.cpython-312.pyc b/tutoring_student/__pycache__/admin.cpython-312.pyc index d30f0f7..cb9ff56 100644 Binary files a/tutoring_student/__pycache__/admin.cpython-312.pyc and b/tutoring_student/__pycache__/admin.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/backends.cpython-312.pyc b/tutoring_student/__pycache__/backends.cpython-312.pyc index 304e16d..b59c363 100644 Binary files a/tutoring_student/__pycache__/backends.cpython-312.pyc and b/tutoring_student/__pycache__/backends.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/models.cpython-312.pyc b/tutoring_student/__pycache__/models.cpython-312.pyc index b58acba..9e51a68 100644 Binary files a/tutoring_student/__pycache__/models.cpython-312.pyc and b/tutoring_student/__pycache__/models.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/tests.cpython-312.pyc b/tutoring_student/__pycache__/tests.cpython-312.pyc index d037f56..ea32d95 100644 Binary files a/tutoring_student/__pycache__/tests.cpython-312.pyc and b/tutoring_student/__pycache__/tests.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/urls.cpython-312.pyc b/tutoring_student/__pycache__/urls.cpython-312.pyc index ed1a918..99ba0c9 100644 Binary files a/tutoring_student/__pycache__/urls.cpython-312.pyc and b/tutoring_student/__pycache__/urls.cpython-312.pyc differ diff --git a/tutoring_student/__pycache__/views.cpython-312.pyc b/tutoring_student/__pycache__/views.cpython-312.pyc index 8449468..58072b0 100644 Binary files a/tutoring_student/__pycache__/views.cpython-312.pyc and b/tutoring_student/__pycache__/views.cpython-312.pyc differ diff --git a/tutoring_student/admin.py b/tutoring_student/admin.py index bc32fb0..fe72f26 100644 --- a/tutoring_student/admin.py +++ b/tutoring_student/admin.py @@ -1,7 +1,18 @@ from django.contrib import admin -from .models import Tutor, Student, TutoringSession +from .models import * +class RecurringInline(admin.TabularInline): + model = RecurringSession.sessions.through + +class RecurringAdmin(admin.ModelAdmin): + """Recurring admin.""" + model = RecurringSession + inlines = [ + RecurringInline, + ] + exclude = ('sessions',) # Register your models here. admin.site.register(Tutor) admin.site.register(Student) admin.site.register(TutoringSession) +admin.site.register(RecurringSession, RecurringAdmin) \ No newline at end of file diff --git a/tutoring_student/migrations/0003_tutoringsession_isrecurring_recurringsession.py b/tutoring_student/migrations/0003_tutoringsession_isrecurring_recurringsession.py new file mode 100644 index 0000000..e14ada5 --- /dev/null +++ b/tutoring_student/migrations/0003_tutoringsession_isrecurring_recurringsession.py @@ -0,0 +1,70 @@ +# Generated by Django 5.0.3 on 2024-03-16 17:52 + +import django.core.validators +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tutoring_student", "0002_alter_student_additionalcomments_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="tutoringsession", + name="isRecurring", + field=models.BooleanField(default=False), + ), + migrations.CreateModel( + name="RecurringSession", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("dayOfWeek", models.CharField(max_length=10)), + ("time", models.TimeField(verbose_name="Time of Session")), + ("startDate", models.DateField(verbose_name="Starting Date")), + ("endDate", models.DateField(verbose_name="Ending Date")), + ( + "duration", + models.DecimalField( + decimal_places=1, + max_digits=2, + validators=[django.core.validators.MaxValueValidator(1.5)], + verbose_name="Duration of Session (Hours)", + ), + ), + ("subject", models.CharField(max_length=100)), + ( + "description", + models.TextField( + verbose_name="Further Description of Student Needs" + ), + ), + ("gradeLevel", models.CharField(max_length=100)), + ("preferredPlatform", models.CharField(default="Zoom", max_length=100)), + ( + "student", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="tutoring_student.student", + ), + ), + ( + "tutor", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="tutoring_student.tutor", + ), + ), + ], + ), + ] diff --git a/tutoring_student/migrations/0004_recurringsession_sessions.py b/tutoring_student/migrations/0004_recurringsession_sessions.py new file mode 100644 index 0000000..f9618d0 --- /dev/null +++ b/tutoring_student/migrations/0004_recurringsession_sessions.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.3 on 2024-03-17 02:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tutoring_student", "0003_tutoringsession_isrecurring_recurringsession"), + ] + + operations = [ + migrations.AddField( + model_name="recurringsession", + name="sessions", + field=models.ManyToManyField(to="tutoring_student.tutoringsession"), + ), + ] diff --git a/tutoring_student/migrations/0005_alter_recurringsession_sessions.py b/tutoring_student/migrations/0005_alter_recurringsession_sessions.py new file mode 100644 index 0000000..f5d81a1 --- /dev/null +++ b/tutoring_student/migrations/0005_alter_recurringsession_sessions.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.3 on 2024-03-17 03:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tutoring_student", "0004_recurringsession_sessions"), + ] + + operations = [ + migrations.AlterField( + model_name="recurringsession", + name="sessions", + field=models.ManyToManyField( + blank=True, default=[], to="tutoring_student.tutoringsession" + ), + ), + ] diff --git a/tutoring_student/models.py b/tutoring_student/models.py index b564929..aaaba4f 100644 --- a/tutoring_student/models.py +++ b/tutoring_student/models.py @@ -50,15 +50,7 @@ class TutoringSession(models.Model): """ def __str__(self): - return ( - self.student.studentName - + " - " - + str(self.date) - + " - " - + str(self.time) - + " - " - + self.subject - ) + return self.student.studentName + " - " + str(self.date) # Session Information date = models.DateField("Date of Session") @@ -73,6 +65,7 @@ def __str__(self): description = models.TextField("Further Description of Student Needs") gradeLevel = models.CharField(max_length=100) preferredPlatform = models.CharField(default="Zoom", max_length=100) + isRecurring = models.BooleanField(default=False) # Personal Information student = models.ForeignKey(Student, on_delete=models.CASCADE) @@ -87,3 +80,97 @@ def is_today(self): def has_tutor(self): return self.tutor is not None + + +class RecurringSession(models.Model): + """ + Model for recurring session + """ + + def __str__(self): + return ( + self.student.studentName + + " - " + + self.tutor.tutorName + + " - " + + self.dayOfWeek + ) + + # Recurring session information + student = models.ForeignKey(Student, on_delete=models.CASCADE) + tutor = models.ForeignKey(Tutor, on_delete=models.CASCADE) + sessions = models.ManyToManyField(TutoringSession, default=[], blank=True) # all sessions related to this recurring + dayOfWeek = models.CharField(max_length=10) + time = models.TimeField("Time of Session") + startDate = models.DateField("Starting Date") + endDate = models.DateField("Ending Date") + duration = models.DecimalField( + "Duration of Session (Hours)", + max_digits=2, + decimal_places=1, + validators=[MaxValueValidator(1.5)], + ) + subject = models.CharField(max_length=100) + description = models.TextField("Further Description of Student Needs") + gradeLevel = models.CharField(max_length=100) + preferredPlatform = models.CharField(default="Zoom", max_length=100) + + def was_in_the_past(self): + """Tests if the recurring sessions has ended + + Returns: + bool: True if the recurring session has ended, False otherwise + """ + return self.endDate < timezone.now().date() + + def generate_sessions(self): + """Generate all sessions for the recurring session given startDate and endDate and daysOfWeek + + Returns: + bool: True if sessions have been generated successfully + """ + days = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", + ] + assert self.dayOfWeek in days + try: + self.generate_sessions_helper(day=days.index(self.dayOfWeek)) + return True + except: + return False + + def generate_sessions_helper(self, day): + """Helper function to generate all sessions for the recurring session given a day of the week + + Args: + day (int): day of the week, 0 for Monday, 1 for Tuesday, ..., 6 for Sunday + + Returns: + bool: True if sessions have been generated successfully + """ + start = datetime.datetime.strptime(self.startDate, "%Y-%m-%d").date() + end = datetime.datetime.strptime(self.endDate, "%Y-%m-%d").date() + while start <= end: + if start.weekday() == day: + session = TutoringSession( + date=start, + time=self.time, + duration=self.duration, + subject=self.subject, + description=self.description, + gradeLevel=self.gradeLevel, + preferredPlatform=self.preferredPlatform, + student=self.student, + tutor=self.tutor, + isRecurring=True, + ) + session.save() + self.sessions.add(session) + start += datetime.timedelta(days=1) + return True diff --git a/tutoring_student/templates/tutoring_student/index.html b/tutoring_student/templates/tutoring_student/index.html index ca17ad4..67643b3 100644 --- a/tutoring_student/templates/tutoring_student/index.html +++ b/tutoring_student/templates/tutoring_student/index.html @@ -292,7 +292,7 @@

- diff --git a/tutoring_student/templates/tutoring_student/recurring_details.html b/tutoring_student/templates/tutoring_student/recurring_details.html new file mode 100644 index 0000000..4d923d3 --- /dev/null +++ b/tutoring_student/templates/tutoring_student/recurring_details.html @@ -0,0 +1,128 @@ + + + + + + + {% load static %} + + + Iridium Tutoring | Tutor + + + + {% load static %} + + + {% if user %} +
+

{{recurring.student.studentName}}'s Recurring Session

+
+ + Go Back +
+ + {% endif %} + + {% include 'tutoring_student/footer.html' %} + + + diff --git a/tutoring_student/templates/tutoring_student/session-student.html b/tutoring_student/templates/tutoring_student/session-student.html index aa417fd..5aca549 100644 --- a/tutoring_student/templates/tutoring_student/session-student.html +++ b/tutoring_student/templates/tutoring_student/session-student.html @@ -132,12 +132,14 @@

{% else %}

- {{tutoringSession.tutor.tutorName}} has signed up for your session and + {{tutoringSession.tutor.tutorName}} {% if tutoringSession.isRecurring %} is your designated recurring tutor. Please contact them + with any questions. + {% else %} has signed up for your session and will reach out soon about the details of your session. If you have any questions, feel free to contact us at iridiumtutoring@gmail.com. + >. {% endif %}

{% endif %} diff --git a/tutoring_student/templates/tutoring_student/session-tutor.html b/tutoring_student/templates/tutoring_student/session-tutor.html index 4af2ef6..8f99124 100644 --- a/tutoring_student/templates/tutoring_student/session-tutor.html +++ b/tutoring_student/templates/tutoring_student/session-tutor.html @@ -69,6 +69,7 @@

{{ tutoringSession.student.studentName }}'s registrationTutor: {{ tutoringSession.tutor.tutorName }} - {{tutoringSession.tutor.email}} {% endif %} + {% if not tutoringSession.isRecurring %} {% if not tutoringSession.tutor %}

You may contact the student via their email of phone number to ask any additional questions about their request. If the student asks to change the time/topic, please contact an administrator to update the session accordingly. To claim this session, press the claim session button below and follow up with an email to the student.

@@ -85,6 +86,7 @@

{{ tutoringSession.student.studentName }}'s registration{{tutoringSession.tutor.tutorName}} has signed up for this session.

{% endif %} + {% endif %} Go Back {% endif %} diff --git a/tutoring_student/templates/tutoring_student/studentView.html b/tutoring_student/templates/tutoring_student/studentView.html index fe8eae5..f18970d 100644 --- a/tutoring_student/templates/tutoring_student/studentView.html +++ b/tutoring_student/templates/tutoring_student/studentView.html @@ -80,8 +80,10 @@

Upcoming Tutoring Sessions

{{session.student.studentName}} - {{session.subject}} (Grade {{session.gradeLevel}})
{% if session.was_in_the_past %} Past + {% elif session.isRecurring %} + Upcoming (Recurring) {% elif session.tutor %} - Upcoming (Tutor Confirmed) + Upcoming (Tutor Confirmed) {% else %} Upcoming (Tutor Pending) {% endif %} diff --git a/tutoring_student/templates/tutoring_student/tutorProfile.html b/tutoring_student/templates/tutoring_student/tutorProfile.html index 306a163..d9e0419 100644 --- a/tutoring_student/templates/tutoring_student/tutorProfile.html +++ b/tutoring_student/templates/tutoring_student/tutorProfile.html @@ -28,6 +28,7 @@ Home Tutors Profile + Utilities diff --git a/tutoring_student/templates/tutoring_student/tutorRecurrings.html b/tutoring_student/templates/tutoring_student/tutorRecurrings.html new file mode 100644 index 0000000..fd7c84e --- /dev/null +++ b/tutoring_student/templates/tutoring_student/tutorRecurrings.html @@ -0,0 +1,367 @@ + + + + + + + {% load static %} + + + Iridium Tutoring | Tutor + + + + {% load static %} + + + {% if user %} +
+

Your Current Recurrings

+
+
+ + {% for recurring in recurringSessions %} + {% if not recurring.was_in_the_past %} +
+
+
{{recurring.student.studentName}} - {{recurring.subject}}
+

+ {{recurring.dayOfWeek}}s at {{recurring.time}} for + {{recurring.duration}} hours
+ From: {{recurring.startDate}} +
+ To: {{recurring.endDate}} +
+ Additional Notes:
+ {{recurring.description}} +

+ More Information +
+
+ {% endif %} + {% endfor %} +
+
+ + +
+

Your Past Recurrings

+
+
+ + {% for recurring in recurringSessions %} + {% if recurring.was_in_the_past %} +
+
+
{{recurring.student.studentName}} - {{recurring.subject}}
+

+ {{recurring.dayOfWeek}}s at {{recurring.time}} for + {{recurring.duration}} hours
+ From: {{recurring.startDate}} +
+ To: {{recurring.endDate}} +
+ Additional Notes:
+ {{recurring.description}} +

+
+
+ {% endif %} + {% endfor %} +
+
+ + +
+
+

Create A Recurring

+
+ +
+
+
+ + {% csrf_token %} + +
+ + +
+ If the student name does not exist, please ask them to register for at least one session with Iridium Tutoring. +
+
+ +
+ + +
+ To register for multiple days of the week, you must submit a separate recurrings form for each day. +
+
+ +
+ + +
+ Even if your times change by day, place an approximate time for our records. +
+
+ +
+ + +
+ Most commonly, sessions are 0.5, 1, or 1.5 hours. +
+
+ +
+ + +
+ +
+ + +
+ Please ensure your end date is after your start date. +
+
+ +
+ + +
+ +
+ + +
+ Please specify the specific topic to be covered. (i.e. SAT + Math - Right Angle Geometry) +
+
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+
+
+
+ + {% endif %} + + + + {% include 'tutoring_student/footer.html' %} + + + diff --git a/tutoring_student/templates/tutoring_student/tutorUtilities.html b/tutoring_student/templates/tutoring_student/tutorUtilities.html new file mode 100644 index 0000000..ff53b19 --- /dev/null +++ b/tutoring_student/templates/tutoring_student/tutorUtilities.html @@ -0,0 +1,176 @@ + + + + + + + {% load static %} + + + Iridium Tutoring | Tutor + + + + {% load static %} + + + {% if user %} +
+

Tutor Utilities

+
+
+ +
+ Discord Logo +
+
Discord Server
+

+ Internal server for communication between board of directors, + staff, and tutors. Strictly invite-only. +

+ Server Invite +
+
+ +
+ Iridium Logo +
+
Information Hub
+

+ Tutorials and How-To information for tutors, onboarding, + staff, board of directors, etc. +

+ Take Me There +
+
+ + +
+ Iridium Logo +
+
Recurrings
+

+ Create, read, update, destroy (CRUD) your upcoming/past recurring sessions. +

+ Go To Tool +
+
+
+
+ {% endif %} + + {% include 'tutoring_student/footer.html' %} + + + diff --git a/tutoring_student/templates/tutoring_student/tutorView.html b/tutoring_student/templates/tutoring_student/tutorView.html index 56faea9..1441cc1 100644 --- a/tutoring_student/templates/tutoring_student/tutorView.html +++ b/tutoring_student/templates/tutoring_student/tutorView.html @@ -70,6 +70,7 @@ Tutors {% if user %} Profile + Utilities {% endif %} @@ -112,7 +113,7 @@

- +

Your Upcoming Tutoring Sessions

@@ -124,6 +125,9 @@

Your Upcoming Tutoring Sessions

{{session.student.studentName}} - {{session.subject}} (Grade {{session.gradeLevel}})
+ {% if session.isRecurring %} + Recurring + {% endif %}
{{session.date}} - {{session.time}} ({{session.duration}} hours) @@ -140,7 +144,7 @@

Available Tutoring Sessions

{% if tutoringSessionList %}
{% for session in tutoringSessionList %} - {% if not session.was_in_the_past %} + {% if not session.was_in_the_past and not session.isRecurring %}
{{session.student.studentName}} - {{session.subject}} (Grade {{session.gradeLevel}})
diff --git a/tutoring_student/tests.py b/tutoring_student/tests.py index 1062a13..f47638d 100644 --- a/tutoring_student/tests.py +++ b/tutoring_student/tests.py @@ -7,6 +7,9 @@ class TutoringSessionModelTest(TestCase): def setUp(self): + """ + Set up a tutoring session and form data for testing. + """ self.form_data = { "date": timezone.now().date(), "time": timezone.now().time(), @@ -18,13 +21,42 @@ def setUp(self): "name": " John Doe ", "email": "johndoe@gmail.com ", } + time = timezone.now() + self.session = TutoringSession( + date=time.date(), + time=timezone.now().time(), + duration=1, + subject="Math", + description="Help with math", + gradeLevel="12", + preferredPlatform="Zoom", + student=Student(studentName="John Doe", email="johndoe@gmail.com"), + ) def test_was_in_past_with_future_date(self): """ was_in_the_past() returns False for sessions in the future. """ time = timezone.now() + datetime.timedelta(days=30) - future_session = TutoringSession( + future_session = self.session + future_session.date = time.date() + self.assertIs(future_session.was_in_the_past(), False) + + def test_was_in_past_with_past_date(self): + """ + was_in_the_past() returns True for sessions in the past. + """ + time = timezone.now() - datetime.timedelta(days=1) + past_session = self.session + past_session.date = time.date() + self.assertIs(past_session.was_in_the_past(), True) + + def test_is_today(self): + """ + is_today() returns True for sessions that are today. + """ + time = timezone.now() + today_session = TutoringSession( date=time.date(), time=timezone.now().time(), duration=1, @@ -34,14 +66,14 @@ def test_was_in_past_with_future_date(self): preferredPlatform="Zoom", student=Student(studentName="John Doe", email="johndoe@gmail.com"), ) - self.assertIs(future_session.was_in_the_past(), False) + self.assertIs(today_session.is_today(), True) - def test_was_in_past_with_past_date(self): + def test_has_tutor(self): """ - was_in_the_past() returns True for sessions in the past. + has_tutor() returns True for sessions that have a tutor object in its field. """ - time = timezone.now() - datetime.timedelta(days=1) - past_session = TutoringSession( + time = timezone.now() + session = TutoringSession( date=time.date(), time=timezone.now().time(), duration=1, @@ -50,8 +82,9 @@ def test_was_in_past_with_past_date(self): gradeLevel="12", preferredPlatform="Zoom", student=Student(studentName="John Doe", email="johndoe@gmail.com"), + tutor=Tutor(tutorName="John Doe", email="johndoe@yahoo.com"), ) - self.assertIs(past_session.was_in_the_past(), True) + self.assertIs(session.has_tutor(), True) def test_register_session_form_not_from_index(self): """ @@ -83,3 +116,53 @@ def test_register_session_form_from_index(self): ), 1, ) + + +class RecurringSessionModelTest(TestCase): + def setUp(self): + """ + Set up a recurring session for testing. + """ + time = timezone.now() + student = Student(studentName="John Student", email="johndoe@gmail.com") + tutor = Tutor(tutorName="John Tutor", email="johndoe@gmail.com") + self.recurring = RecurringSession( + student=student, + tutor=tutor, + dayOfWeek="Monday", + time=time.time(), + startDate=time.date(), + endDate=time.date() + datetime.timedelta(days=100), + duration=1, + subject="Math", + description="Help with math", + gradeLevel="12", + preferredPlatform="Zoom", + ) + + def test_generate_sessions(self): + """ + generate_sessions() returns True for sessions that have been generated. + """ + self.assertIs(self.recurring.generate_sessions(), True) + self.assertIs(self.recurring.sessions[0].isRecurring, True) + print(self.recurring.sessions) + + def test_sort_session(self): + """ + sort_session() returns True for sessions that have been sorted. + """ + self.recurring.generate_sessions() + self.assertIs(self.recurring.sort_session(), True) + for i in range(len(self.recurring.sessions) - 1): + self.assertLessEqual( + self.recurring.sessions[i].date, self.recurring.sessions[i + 1].date + ) + + def test_was_in_past(self): + """ + was_in_the_past() returns True for sessions that have ended. + """ + self.assertIs(self.recurring.was_in_the_past(), False) + self.recurring.endDate = timezone.now().date() - datetime.timedelta(days=1) + self.assertIs(self.recurring.was_in_the_past(), True) diff --git a/tutoring_student/urls.py b/tutoring_student/urls.py index ca703cd..ca6d535 100644 --- a/tutoring_student/urls.py +++ b/tutoring_student/urls.py @@ -14,5 +14,8 @@ path("studentPortal/session-student//", views.session_details_student, name="session_details_student"), path("tutorPortal/session-tutor//", views.session_details_tutor, name="session_details_tutor"), path("tutorPortal/profile", views.tutorProfile, name="tutorProfile"), + path("tutorPortal/utilities", views.tutorUtilities, name="tutorUtilities"), + path("tutorPortal/utilities/recurrings", views.tutorRecurrings, name="tutorRecurrings"), + path("tutorPortal/utilities/recurrings//", views.recurring_details, name="recurring_details"), path("session-confirmation/", views.sessionConfirmation, name="register_session"), ] diff --git a/tutoring_student/views.py b/tutoring_student/views.py index dc12dc6..b9f9bd2 100644 --- a/tutoring_student/views.py +++ b/tutoring_student/views.py @@ -176,6 +176,64 @@ def send_confirmation_email(context, email): ) +def register_recurring_session(request, data): + """Register recurring session given form data + + Args: + request (Django HTTP request): passed from previous view + data (dict): form data + """ + + # Check validity of form data (Start/End data, nullity) + if ( + data["startDate"] == "" + or data["tutor"] == None + or data["endDate"] == "" + or data["student"] == None + or data["dayOfWeek"] == "" + or data["time"] == "" + or data["duration"] == "" + or data["subject"] == "" + or data["description"] == "" + or data["gradeLevel"] == "" + or data["platform"] == "" + ): + raise Http404("Data fields missing.") + if data["startDate"] >= data["endDate"]: + raise Http404("Start date must be before end date.") + + try: + # Create recurring session object + recurring = RecurringSession( + student=data["student"], + tutor=data["tutor"], + dayOfWeek=data["dayOfWeek"], + time=data["time"], + duration=data["duration"], + startDate=data["startDate"], + endDate=data["endDate"], + subject=data["subject"], + description=data["description"], + gradeLevel=data["gradeLevel"], + preferredPlatform=data["platform"], + ) + + # Check if recurring session already exists + if not RecurringSession.objects.filter( + student=data["student"], + dayOfWeek=data["dayOfWeek"], + time=data["time"], + startDate=data["startDate"], + ).first(): + recurring.save() # Save recurring session so Many-To-Many relationship can be established + recurring.generate_sessions() + return recurring + return None + except Exception as e: + print(e) + raise Http404("There was an error generating the sessions.") + + #### VIEWS #### @@ -391,6 +449,96 @@ def tutorProfile(request): return render(request, "tutoring_student/tutorProfile.html", context) +@user_passes_test(check_tutor) +def tutorUtilities(request): + """Tutor utilities view + + Args: + request (Django HTTP request): passed from previous view + + Returns: + tutorUtilities: render tutorUtilities.html with context + """ + try: + tutor = get_tutor(request, request.user) + except: + raise Http404("You are not authorized to access this page.") + context = {"tutor": tutor, "user": tutor != None} + return render(request, "tutoring_student/tutorUtilities.html", context) + + +@user_passes_test(check_tutor) +def tutorRecurrings(request): + """Tutor recurrings view + + Args: + request (Django HTTP request): passed from previous view + + Returns: + tutorRecurrings: render tutorRecurrings.html with context + """ + + try: + tutor = get_tutor(request, request.user) + except: + raise Http404("You are not authorized to access this page.") + + # Get form data from create recurrings + if request.method == "POST": + name = request.POST.get("studentName", "").strip() + data = { + "student": Student.objects.get(studentName=name), + "tutor": tutor, + "dayOfWeek": request.POST.get("dayOfWeek", "").strip(), + "time": request.POST.get("time", "").strip(), + "duration": request.POST.get("duration", 1).strip(), + "startDate": request.POST.get("startDate", "").strip(), + "endDate": request.POST.get("endDate", "").strip(), + "subject": request.POST.get("subject", "").strip(), + "description": request.POST.get("description", "").strip(), + "gradeLevel": request.POST.get("gradeLevel", "").strip(), + "platform": request.POST.get("platform", "").strip(), + } + try: + recurring = register_recurring_session(request, data) + except Exception as e: + print(e) + raise Http404("There was an error creating the recurring session.") + + recurringSessions = RecurringSession.objects.filter(tutor=tutor) + allStudents = Student.objects.all() + context = { + "tutor": tutor, + "user": tutor != None, + "recurringSessions": recurringSessions, + "allStudents": allStudents, + } + return render(request, "tutoring_student/tutorRecurrings.html", context) + + +@user_passes_test(check_tutor) +def recurring_details(request, recurring_id): + """Recurring details view + + Args: + request (Django HTTP request): passed from previous view + recurring_id (int): foreign key for recurring session object + + Raises: + Http404: if recurring session does not exist or tutor is not authorized + + Returns: + recurring_details: render recurring_details.html with context + """ + try: + tutor = get_tutor(request, request.user) + except: + raise Http404("You are not authorized to access this page.") + recurring = get_object_or_404(RecurringSession, pk=recurring_id) + context = {"recurring": recurring, "tutor": tutor, "user": tutor != None} + return render(request, "tutoring_student/recurring_details.html", context) + + def sessionConfirmation(request): """ Session confirmation view @@ -457,7 +605,7 @@ def sessionConfirmation(request): # Send confirmation email and save tutoring session object else: try: - send_confirmation_email(context, email) + # send_confirmation_email(context, email) t.save() except: context["error_message"] = (