From 4fbc91f70ab5e2cb8ef17e57ecd369d2c137e983 Mon Sep 17 00:00:00 2001 From: Linda Ramos Date: Tue, 8 Jun 2021 15:03:46 -0600 Subject: [PATCH] added SessionCancelView to admin, mentors --- coderdojochi/models/session.py | 3 + .../templates/guardian/session_cancel.html | 33 +++++ .../templates/mentor/session_cancel.html | 21 +++ .../templates/mentor/session_detail.html | 2 +- .../templates/mentor/session_sign_up.html | 24 +--- coderdojochi/urls.py | 7 + coderdojochi/views/guardian/sessions.py | 3 + coderdojochi/views/mentor/sessions.py | 52 ++++++- coderdojochi/views/sessions.py | 133 ++++-------------- fixtures/12-coderdojochi.mentor.json | 12 +- fixtures/14-coderdojochi.session.json | 2 +- fixtures/15-coderdojochi.mentororder.json | 17 +++ 12 files changed, 177 insertions(+), 132 deletions(-) create mode 100644 coderdojochi/templates/guardian/session_cancel.html create mode 100644 coderdojochi/templates/mentor/session_cancel.html diff --git a/coderdojochi/models/session.py b/coderdojochi/models/session.py index cc25f787..8d1cc699 100644 --- a/coderdojochi/models/session.py +++ b/coderdojochi/models/session.py @@ -277,6 +277,9 @@ def get_absolute_url(self) -> str: def get_sign_up_url(self): return reverse("session-sign-up", args=[str(self.id)]) + def get_cancel_url(self): + return reverse("session-cancel", args=[str(self.id)]) + def get_calendar_url(self): return reverse("session-calendar", args=[str(self.id)]) diff --git a/coderdojochi/templates/guardian/session_cancel.html b/coderdojochi/templates/guardian/session_cancel.html new file mode 100644 index 00000000..b0718727 --- /dev/null +++ b/coderdojochi/templates/guardian/session_cancel.html @@ -0,0 +1,33 @@ +{% extends "coderdojochi/_base.html" %} + +{% load i18n %} + +{% block title %}{{ session.course.title }} Sign Up | {{ block.super }}{% endblock %} + +{% block body_class %}page-class-sign-up{% endblock %} + +{% block contained_content %} +
+ {% if user_signed_up %} + +

{{ student.full_name }} can no longer make it to the "{{ session.course.title }}" class on {{ session.start_date|date }} from {{ session.start_date|time }} to {{ session.end_date|time }}.

+ +
+ {% csrf_token %} + + Nevermind +
+ + {% else %} + +

Enroll {{ student.full_name }} for the "{{ session.course.title }}" class on {{ session.start_date|date }} from {{ session.start_date|time }} to {{ session.end_date|time }}.

+ +
+ {% csrf_token %} + + Nevermind +
+ + {% endif %} +
+{% endblock %} diff --git a/coderdojochi/templates/mentor/session_cancel.html b/coderdojochi/templates/mentor/session_cancel.html new file mode 100644 index 00000000..43af4f33 --- /dev/null +++ b/coderdojochi/templates/mentor/session_cancel.html @@ -0,0 +1,21 @@ +{% extends "coderdojochi/_base.html" %} + +{% load i18n %} + +{% block title %}{{ session.course.title }} Cancel | {{ block.super }}{% endblock %} + +{% block body_class %}page-class-sign-up{% endblock %} + +{% block contained_content %} +
+ +

I can no longer volunteer for the "{{ session.course.title }}" class on {{ session.mentor_start_date|date }} from {{ session.mentor_start_date|time }} to {{ session.mentor_end_date|time }}.

+ +
+ {% csrf_token %} + + Nevermind +
+ +
+{% endblock %} diff --git a/coderdojochi/templates/mentor/session_detail.html b/coderdojochi/templates/mentor/session_detail.html index ed9b01e9..2c012579 100644 --- a/coderdojochi/templates/mentor/session_detail.html +++ b/coderdojochi/templates/mentor/session_detail.html @@ -26,7 +26,7 @@

Class Details & Enrollment

{% else %} {% if mentor_signed_up %}

You are signed up to mentor this class.

-

I can't make it...

+

I can't make it...

{% else %} {% if spots_remaining %}

Sign up now!

diff --git a/coderdojochi/templates/mentor/session_sign_up.html b/coderdojochi/templates/mentor/session_sign_up.html index b53cef13..d1d1781d 100644 --- a/coderdojochi/templates/mentor/session_sign_up.html +++ b/coderdojochi/templates/mentor/session_sign_up.html @@ -8,26 +8,14 @@ {% block contained_content %}
- {% if user_signed_up %} -

I can no longer volunteer for the "{{ session.course.title }}" class on {{ session.mentor_start_date|date }} from {{ session.mentor_start_date|time }} to {{ session.mentor_end_date|time }}.

+

Sign up to mentor for the "{{ session.course.title }}" class on {{ session.mentor_start_date|date }} from {{ session.mentor_start_date|time }} to {{ session.mentor_end_date|time }}.

-
- {% csrf_token %} - - Nevermind -
+
+ {% csrf_token %} + + Nevermind +
- {% else %} - -

Sign up to mentor for the "{{ session.course.title }}" class on {{ session.mentor_start_date|date }} from {{ session.mentor_start_date|time }} to {{ session.mentor_end_date|time }}.

- -
- {% csrf_token %} - - Nevermind -
- - {% endif %}
{% endblock %} diff --git a/coderdojochi/urls.py b/coderdojochi/urls.py index 924c4cb8..263bda40 100644 --- a/coderdojochi/urls.py +++ b/coderdojochi/urls.py @@ -16,6 +16,7 @@ SessionCalendarView, SessionDetailView, SessionSignUpView, + SessionCancelView, WelcomeView, meeting_announce, meeting_sign_up, @@ -156,6 +157,12 @@ path("/sign-up/", SessionSignUpView.as_view(), name="session-sign-up"), # /classes/ID/sign-up/STUDENT-ID/ path("/sign-up//", SessionSignUpView.as_view(), name="session-sign-up"), + + # Cancel session + # /classes/ID/cancel/ + path("/cancel/", SessionCancelView.as_view(), name="session-cancel"), + # /classes/ID/cancel/STUDENT-ID/ + path("/cancel//", SessionCancelView.as_view(), name="session-cancel"), ] ), ), diff --git a/coderdojochi/views/guardian/sessions.py b/coderdojochi/views/guardian/sessions.py index 7cb1a57f..0404fa2e 100644 --- a/coderdojochi/views/guardian/sessions.py +++ b/coderdojochi/views/guardian/sessions.py @@ -19,3 +19,6 @@ def get_context_data(self, **kwargs): ) return context + +class SessionCancelView(DetailView): + pass diff --git a/coderdojochi/views/mentor/sessions.py b/coderdojochi/views/mentor/sessions.py index 1defa2a6..46e7b80f 100644 --- a/coderdojochi/views/mentor/sessions.py +++ b/coderdojochi/views/mentor/sessions.py @@ -1,4 +1,5 @@ -from django.shortcuts import get_object_or_404 +from django.core.exceptions import ObjectDoesNotExist +from django.shortcuts import get_object_or_404, redirect from django.views.generic import DetailView from ...models import Mentor, MentorOrder, Session @@ -14,12 +15,11 @@ def get_context_data(self, **kwargs): session_orders = MentorOrder.objects.filter( session=session, - mentor=mentor, is_active=True, ) context = super().get_context_data(**kwargs) - context["mentor_signed_up"] = session_orders.exists() + context["mentor_signed_up"] = session_orders.filter(mentor=mentor).exists() context["spots_remaining"] = session.mentor_capacity - session_orders.count() context["account"] = mentor @@ -31,3 +31,49 @@ def get_context_data(self, **kwargs): ) return context + + +class SessionCancelView(DetailView): + model = Session + template_name = "mentor/session_cancel.html" + + # redirect if order not found + def get(self, request, *args, **kwargs): + try: + self.object = self.get_object() + session = self.object + mentor = get_object_or_404(Mentor, user=self.request.user) + mentor_order = MentorOrder.objects.get( + session=session, + mentor=mentor, + is_active=True, + ) + context = self.get_context_data(object=self.object) + return self.render_to_response(context) + except ObjectDoesNotExist: + return redirect(session.get_absolute_url()) + + + def get_context_data(self, **kwargs): + session = self.object + mentor = get_object_or_404(Mentor, user=self.request.user) + + mentor_order = MentorOrder.objects.get( + session=session, + mentor=mentor, + is_active=True, + ) + + context = super().get_context_data(**kwargs) + # context["mentor_signed_up"] = session_orders.filter(mentor=mentor).exists() + # context["spots_remaining"] = session.mentor_capacity - session_orders.count() + # context["account"] = mentor + + # context["active_mentors"] = Mentor.objects.filter( + # id__in=MentorOrder.objects.filter( + # session=self.object, + # is_active=True, + # ).values("mentor__id") + # ) + + return context diff --git a/coderdojochi/views/sessions.py b/coderdojochi/views/sessions.py index 63f9bc18..d0f37ca6 100644 --- a/coderdojochi/views/sessions.py +++ b/coderdojochi/views/sessions.py @@ -136,109 +136,6 @@ def validate_partner_session_access(self, request, pk): return False -# class SessionDetailView(RoleRedirectMixin, RoleTemplateMixin, TemplateView): -# template_name = "session_detail.html" - -# def dispatch(self, request, *args, **kwargs): -# session_obj = get_object_or_404(Session, id=kwargs["pk"]) - -# if request.method == "GET": -# if session_obj.password and not self.validate_partner_session_access(self.request, kwargs["pk"]): -# return redirect(reverse("session-password", kwargs=kwargs)) - -# if request.user.is_authenticated and request.user.role: -# if "enroll" in request.GET or "enroll" in kwargs: -# return self.enroll_redirect(request, session_obj) - -# # kwargs["session_obj"] = session_obj -# return super(SessionDetailView, self).dispatch(request, *args, **kwargs) - -# def enroll_redirect(self, request, session_obj): -# if request.user.role == "mentor": -# return redirect("session-sign-up", pk=session_obj.id) - -# guardian = get_object_or_404(Guardian, user=request.user) -# student = get_object_or_404(Student, guardian=guardian, id=(int(request.GET["student"]))) - -# if student: -# return redirect("session-sign-up", pk=session_obj.id, student_id=student.id) - -# return redirect(f"{reverse('welcome')}?next={session_obj.get_absolute_url()}&enroll=True") - -# def validate_partner_session_access(self, request, pk): -# authed_sessions = request.session.get("authed_partner_sessions") - -# if authed_sessions and pk in authed_sessions: -# if request.user.is_authenticated: -# PartnerPasswordAccess.objects.get_or_create(session_id=pk, user=request.user) -# return True - -# if request.user.is_authenticated: -# try: -# PartnerPasswordAccess.objects.get(session_id=pk, user_id=request.user.id) -# except PartnerPasswordAccess.DoesNotExist: -# return False -# else: -# return True - -# else: -# return False - -# def get_context_data(self, **kwargs): -# print(kwargs["session_obj"].__dict__) -# context = super(SessionDetailView, self).get_context_data(**kwargs) -# session_obj = kwargs["session_obj"] -# context["session"] = session_obj - -# upcoming_classes = Session.objects.filter(is_active=True, start_date__gte=timezone.now()).order_by("start_date") -# context["upcoming_classes"] = upcoming_classes - -# active_mentors = Mentor.objects.filter( -# id__in=MentorOrder.objects.filter(session=session_obj, is_active=True).values("mentor__id") -# ) -# context["active_mentors"] = active_mentors - -# if self.request.user.is_authenticated: -# if self.request.user.role == "mentor": -# account = get_object_or_404(Mentor, user=self.request.user) -# session_orders = MentorOrder.objects.filter(session=session_obj, is_active=True,) -# context["mentor_signed_up"] = session_orders.filter(mentor=account).exists() - -# context["spots_remaining"] = session_obj.get_mentor_capacity() - session_orders.count() -# else: -# account = get_object_or_404(Guardian, user=self.request.user) -# context["students"] = account.get_students() -# context["spots_remaining"] = session_obj.capacity - session_obj.get_active_student_count() -# context["account"] = account -# else: -# context["upcoming_classes"] = upcoming_classes.filter(is_public=True) -# context["spots_remaining"] = session_obj.capacity - session_obj.objects.get_active_student_count() - -# return context - -# def post(self, request, *args, **kwargs): -# session_obj = kwargs["session_obj"] -# if "waitlist" not in request.POST: -# messages.error(request, "Invalid request, please try again.") -# return redirect(session_obj.get_absolute_url()) - -# if request.POST["waitlist"] == "student": -# account = Student.objects.get(id=request.POST["account_id"]) -# waitlist_attr = "waitlist_students" -# else: -# account = Guardian.objects.get(id=request.POST["account_id"]) -# waitlist_attr = "waitlist_guardians" - -# if request.POST["remove"] == "true": -# getattr(session_obj, waitlist_attr).remove(account) -# session_obj.save() -# messages.success(request, "You have been removed from the waitlist. Thanks for letting us know.") -# else: -# getattr(session_obj, waitlist_attr).add(account) -# session_obj.save() -# messages.success(request, "Added to waitlist successfully.") -# return redirect(session_obj.get_absolute_url()) - class SessionSignUpView(RoleRedirectMixin, RoleTemplateMixin, TemplateView): template_name = "session_sign_up.html" @@ -254,6 +151,8 @@ def dispatch(self, request, *args, **kwargs): kwargs["mentor"] = get_object_or_404(Mentor, user=request.user) kwargs["user_signed_up"] = session_orders.filter(mentor=kwargs["mentor"]).exists() + kwargs["spots_remaining"] = session_obj.mentor_capacity - session_orders.count() + elif request.user.role == "guardian": kwargs["guardian"] = get_object_or_404(Guardian, user=request.user) kwargs["student"] = get_object_or_404(Student, id=kwargs["student_id"]) @@ -286,6 +185,15 @@ def check_access(self, request, *args, **kwargs): ), "redirect": request.META.get("HTTP_REFERER", "/dojo"), } + + # Check to make sure there is a spot open to sign up + if kwargs["spots_remaining"] <= 0: + access_dict = { + "message": ( + "There are no slots open to mentor. Please check another class." + ), + "redirect": request.META.get("HTTP_REFERER", kwargs["session_obj"].get_absolute_url()), + } if kwargs.get("student"): limits = self.student_limitations(kwargs["student"], kwargs["session_obj"], kwargs["user_signed_up"]) @@ -365,6 +273,25 @@ def post(self, request, *args, **kwargs): return redirect(session_obj.get_absolute_url()) +class SessionCancelView(View): + def get(self, request, *args, **kwargs): + pk = kwargs["pk"] + session = get_object_or_404(Session, id=pk) + + # TODO: Do we need to check for this? + # if session.password and not self.validate_partner_session_access(request, pk): + # return redirect(reverse("session-password", kwargs=kwargs)) + + if request.user.is_authenticated: + if request.user.role == "mentor": + return mentor.SessionCancelView.as_view()(request, *args, **kwargs) + else: + return guardian.SessionCancelView.as_view()(request, *args, **kwargs) + + return redirect(session.get_absolute_url()) + + + class PasswordSessionView(TemplateView): template_name = "session_partner_password.html" diff --git a/fixtures/12-coderdojochi.mentor.json b/fixtures/12-coderdojochi.mentor.json index 0136d45a..388de454 100644 --- a/fixtures/12-coderdojochi.mentor.json +++ b/fixtures/12-coderdojochi.mentor.json @@ -29,16 +29,16 @@ "user": 3, "bio": "", "is_active": true, - "background_check": false, - "is_public": false, + "background_check": true, + "is_public": true, "avatar": "", - "avatar_approved": false, - "birthday": null, - "gender": null, + "avatar_approved": true, + "birthday": "1988-01-01", + "gender": "male", "work_place": null, "phone": null, "home_address": null, - "race_ethnicity": [] + "race_ethnicity": [2] } }, { diff --git a/fixtures/14-coderdojochi.session.json b/fixtures/14-coderdojochi.session.json index bc1e1dcb..2486e1bb 100644 --- a/fixtures/14-coderdojochi.session.json +++ b/fixtures/14-coderdojochi.session.json @@ -9,7 +9,7 @@ "start_date": "2022-01-01T16:00:00Z", "location": 3, "capacity": 20, - "mentor_capacity": 10, + "mentor_capacity": 1, "instructor": 1, "cost": "0.00", "minimum_cost": null, diff --git a/fixtures/15-coderdojochi.mentororder.json b/fixtures/15-coderdojochi.mentororder.json index f6fc874c..4fa7685d 100644 --- a/fixtures/15-coderdojochi.mentororder.json +++ b/fixtures/15-coderdojochi.mentororder.json @@ -15,5 +15,22 @@ "week_reminder_sent": true, "day_reminder_sent": true } +}, +{ + "model": "coderdojochi.mentororder", + "pk": 1, + "fields": { + "created_at": "2016-05-08T19:07:25.346Z", + "updated_at": "2016-05-08T19:07:25.346Z", + "mentor": 1, + "session": 1, + "is_active": true, + "ip": "", + "check_in": "2016-05-07T16:00:00Z", + "affiliate": "", + "order_number": "", + "week_reminder_sent": true, + "day_reminder_sent": true + } } ]