Example #1
0
    def _perform_exchange_pair_success_test_endtoend(self, exchange_left, exchange_right, exchange_left_type, exchange_right_type,
                                                     additional_processed_exchanges=0):
        """Same as the other one, but uses process_process_new_exchange_request for end-to-end testing."""
        globally_processed_exchanges_before = sum(1 for e in Exchange.objects.all() if e.is_finalized())

        if exchange_left.initiator_student:
            self.assertTrue(is_exchange_acceptable(exchange_right, exchange_left.initiator_student))
        if exchange_right.initiator_student:
            self.assertTrue(is_exchange_acceptable(exchange_left, exchange_right.initiator_student))

        params = self._cancel_exchange_get_params(exchange_right)
        any_processed = process_new_exchange_request(**params)
        self.assertTrue(any_processed)

        # pre-check types
        self.assertEqual(exchange_left.get_type(), exchange_left_type)

        new_exchange = Exchange.objects.filter(allocation_from=exchange_right.allocation_from,
                                               allocation_to=exchange_right.allocation_to,
                                               initiator_student=exchange_right.initiator_student,
                                               date_finalized__isnull=False).first()

        self._finalized_exchange_pair_checks(exchange_left, new_exchange)

        # post-check types
        self.assertEqual(exchange_left.get_type(), exchange_left_type)
        self.assertEqual(new_exchange.get_type(), exchange_right_type)

        globally_processed_exchanges_after = sum(1 for e in Exchange.objects.all() if e.is_finalized())
        self.assertEqual(globally_processed_exchanges_before + 2 + additional_processed_exchanges, globally_processed_exchanges_after)
Example #2
0
    def _perform_no_matches_endtoend_test(self, exchange, exchange_type):
        self.assertEqual(exchange.get_type(), exchange_type)

        exchanges_before = Exchange.objects.count()
        globally_processed_exchanges_before = sum(1 for e in Exchange.objects.all() if e.is_finalized())

        params = self._cancel_exchange_get_params(exchange)
        any_processed = process_new_exchange_request(**params)
        self.assertFalse(any_processed)

        exchanges_after = Exchange.objects.count()
        globally_processed_exchanges_after = sum(1 for e in Exchange.objects.all() if e.is_finalized())
        self.assertEqual(globally_processed_exchanges_before, globally_processed_exchanges_after)
        self.assertEqual(exchanges_before + 1, exchanges_after)
Example #3
0
def accept_exchange(request, timetable_slug, exchange_id):
    selected_timetable = get_object_or_404(Timetable, slug=timetable_slug)
    student = Student.from_user(request.user)
    exchange = get_object_or_404(Exchange, id=exchange_id)

    if exchange.is_finalized():
        header = "Exchange already finalized."
        message = "This exchange has already been finalized."
    elif exchange.is_cancelled():
        header = "Exchange cancelled."
        message = "This exchange is cancelled."
    else:
        subject = Activity.from_timetable_activity(
            exchange.allocation_from.activityRealization.activity).subject
        try:
            any_fulfilled = process_new_exchange_request(
                selected_timetable, student, exchange.initiator_student if
                exchange.get_type() == ExchangeType.SPECIFIC_STUDENT else None,
                {subject.id: exchange.allocation_from})
        except FormProcessingError as e:
            return render(
                request, "exchange/exchange_create_result.html", {
                    "selected_timetable": selected_timetable,
                    "header": e.header,
                    "message": e.message
                })
        if any_fulfilled:
            header = "Exchange fulfilled!"
            message = "Your request was fulfilled. Check your new slot on your timetable."
        else:
            header = "Request added to the queue."
            message = "Your request could not be fulfilled immediately and was placed into the queue for it to " \
                      "be fulfilled in the future. Check back at a later date!"
    return render(
        request, "exchange/exchange_create_result.html", {
            "selected_timetable": selected_timetable,
            "header": header,
            "message": message
        })
Example #4
0
def create_exchange_teacher(request, timetable_slug, subject_code):
    selected_timetable = get_object_or_404(Timetable, slug=timetable_slug)
    teacher = request.user.teacher
    subject = get_object_or_404(Subject, code=subject_code)

    if not teacher_teaches_subject(selected_timetable, teacher, subject):
        raise PermissionDenied

    activity_types = ["LAB", "LV", "AV"]

    student_selection_form = StudentSelectionForm(Student.objects,
                                                  data=request.GET)
    if not student_selection_form.is_valid():
        return HttpResponseBadRequest()
    selected_student = student_selection_form.cleaned_data["selected_student"]

    try:
        student_allocation = get_current_student_subject_allocation(
            selected_timetable, selected_student, subject, activity_types)
        available_allocations = get_student_subject_other_allocations(
            selected_timetable, selected_student, subject, activity_types)
    except Allocation.DoesNotExist:
        raise Http404(
            "The student does not attend the subject or no allocations have been found."
        )

    exchange_creation_form = TeacherExchangeCreationForm(
        available_allocations,
        data=request.POST or None,
        initial={
            "timetable": selected_timetable,
            "teacher": teacher,
            "student": selected_student,
            "current_student_allocation": student_allocation
        })

    # first way into this is with a submitted form with a selected student
    if request.method == "GET":
        return render(
            request, "exchange/exchange_create.html", {
                "selected_timetable": selected_timetable,
                "form": exchange_creation_form
            })
    else:
        if exchange_creation_form.is_valid():
            any_fulfilled = process_new_exchange_request(
                exchange_creation_form.cleaned_data["timetable"],
                exchange_creation_form.cleaned_data["teacher"],
                exchange_creation_form.cleaned_data["student"],
                exchange_creation_form.get_subject_transfer_map(),
                # the teacher acts as if they attend the allocation the student wants
                force_allocation_from=exchange_creation_form.
                cleaned_data["requested_student_allocation"])
            if any_fulfilled:
                header = "Exchange fulfilled immediately!"
                message = "The request was fulfilled immediately. Verify the new slot on the timetable.."
            else:
                header = "Request added to the queue."
                message = "The request could not be fulfilled immediately and was placed into the queue for it to " \
                          "be fulfilled in the future."
            return render(
                request, "exchange/exchange_create_result.html", {
                    "selected_timetable": selected_timetable,
                    "header": header,
                    "message": message
                })
            pass
        else:
            return render(
                request, "exchange/exchange_create.html", {
                    "selected_timetable": selected_timetable,
                    "form": exchange_creation_form
                })
Example #5
0
def create_exchange_student(request, timetable_slug):
    selected_timetable = get_object_or_404(Timetable, slug=timetable_slug)

    student = Student.from_user(request.user)
    subjects = get_student_subject_list(selected_timetable, student)
    subject_available_allocation_map = {}
    subject_attending_allocation_map = {}
    for subject in subjects:
        activity_types = ["LAB", "LV", "AV"]
        try:
            student_allocation = get_current_student_subject_allocation(
                selected_timetable, student, subject, activity_types)
            allocations = get_student_subject_other_allocations(
                selected_timetable, student, subject, activity_types)
            subject_available_allocation_map[subject] = allocations
            subject_attending_allocation_map[subject] = student_allocation
        except Allocation.DoesNotExist:
            # don't show subjects the student doesn't have attend labs for
            pass

    if request.method == "POST":
        form = ExchangeCreationForm(subject_available_allocation_map,
                                    subject_attending_allocation_map,
                                    data=request.POST)
        if form.is_valid():
            try:
                requested_student_string = form.get_requested_student()
                requested_student = None
                if requested_student_string:
                    requested_student = parse_student_from_ambiguous_identifier(
                        requested_student_string)
                any_fulfilled = process_new_exchange_request(
                    selected_timetable, student, requested_student,
                    form.get_subject_transfers(keep_empty=False))
            except FormProcessingError as e:
                return render(
                    request, "exchange/exchange_create_result.html", {
                        "selected_timetable": selected_timetable,
                        "header": e.header,
                        "message": e.message
                    })
            if any_fulfilled:
                header = "Exchange fulfilled immediately!"
                message = "Your request was fulfilled immediately. Check your new slot on your timetable."
            else:
                header = "Request added to the queue."
                message = "Your request could not be fulfilled immediately and was placed into the queue for it to " \
                          "be fulfilled in the future. Check back at a later date!"
            return render(
                request, "exchange/exchange_create_result.html", {
                    "selected_timetable": selected_timetable,
                    "header": header,
                    "message": message
                })
        # otherwise fall through to rendering the same form, with the data filled out, as is tradition
    else:
        form = ExchangeCreationForm(subject_available_allocation_map,
                                    subject_attending_allocation_map)

    return render(request, "exchange/exchange_create.html", {
        "selected_timetable": selected_timetable,
        "form": form
    })