From: Yoan Le Clanche Date: Wed, 19 Sep 2018 07:46:51 +0000 (+0200) Subject: dev X-Git-Tag: 1.4.0~39^2~6 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=41556cc2f69960ed80df5bf1ee333b7072394ae4;p=teleforma.git dev --- 41556cc2f69960ed80df5bf1ee333b7072394ae4 diff --cc teleforma/models/appointment.py index 447a2eb7,7297b125..252fb505 --- a/teleforma/models/appointment.py +++ b/teleforma/models/appointment.py @@@ -196,33 -258,15 +258,25 @@@ class Appointment(Model) return self.slot.day @property - def real_time(self): + def start(self): start = self.slot.start delta = self.slot_nb * self.period.appointment_slot_size - dt = datetime.datetime.combine(date.today(), start) + datetime.timedelta(minutes=delta) - dt = datetime.datetime.combine(self.day.date, start) + datetime.timedelta(minutes = delta) - return datetime.time(dt.hour,dt.minute,0) ++ dt = datetime.datetime.combine(datetime.date.today(), start) + datetime.timedelta(minutes=delta) + return datetime.time(dt.hour, dt.minute, 0) + + @property + def end(self): - dt = datetime.datetime.combine(date.today(), self.start) + datetime.timedelta(minutes=self.period.appointment_slot_size) ++ dt = datetime.datetime.combine(datetime.date.today(), self.start) + datetime.timedelta(minutes=self.period.appointment_slot_size) + return datetime.time(dt.hour, dt.minute, 0) + + @property + def arrival(self): - dt = datetime.datetime.combine(date.today(), self.start) - datetime.timedelta(minutes=60) ++ dt = datetime.datetime.combine(datetime.date.today(), self.start) - datetime.timedelta(minutes=60) + return datetime.time(dt.hour, dt.minute, 0) - - # @property - # def real_time(self): - # start = self.slot.start - # delta = self.slot_nb * self.period.appointment_slot_size - # dt = datetime.datetime.combine(date.today(), start) + datetime.timedelta(minutes = delta) - # return datetime.time(dt.hour,dt.minute,0) - @property def real_date(self): - return datetime.datetime.combine(self.day.date, self.real_time) + return datetime.datetime.combine(self.day.date, self.start) @property def real_date_human(self): diff --cc teleforma/templates/teleforma/appointments.html index c42b6421,3f21e462..4ff23ab3 --- a/teleforma/templates/teleforma/appointments.html +++ b/teleforma/templates/teleforma/appointments.html @@@ -77,22 -58,21 +77,22 @@@ $('[name="day-to-show"]').bind('change', updateDisplayedDays); updateDisplayedDays(); - $('.previous_day').click(function() { + $('.previous_day').click(function () { var $select = $(this).parent().find('select'); - if($select.find('option:selected').prev().size()) { - var $selected = $select.find('option:selected'); + if ($select.find('option:selected').prev().size()) { + var selected = $select.val(); $select.find('option').removeAttr('selected'); - $select.find('option[value="' + selected + '"]').prev().attr('selected', 'selected'); - $selected.prev().attr('selected', 'selected'); ++ $select.find('option[value="' + selected + '"]').prev().prop('selected', true); + $select.trigger('change'); } }); - $('.next_day').click(function() { + $('.next_day').click(function () { var $select = $(this).parent().find('select'); - if($select.find('option:selected').next().size()) { - var $selected = $select.find('option:selected'); + if ($select.find('option:selected').next().size()) { + var selected = $select.val(); $select.find('option').removeAttr('selected'); - $select.find('option[value="' + selected + '"]').next().attr('selected', 'selected'); - console.log($selected) - $selected.next().attr('selected', 'selected'); ++ $select.find('option[value="' + selected + '"]').next().prop('selected', true); + $select.trigger('change'); } }); }) diff --cc teleforma/views/appointment.py index fbfbddb6,f6440980..02fd1854 --- a/teleforma/views/appointment.py +++ b/teleforma/views/appointment.py @@@ -1,17 -1,35 +1,37 @@@ # -*- coding: utf-8 -*- from django.views.generic import View - from django.shortcuts import render, redirect +from django.contrib import messages +from django.http import HttpResponse + from django.shortcuts import redirect, get_object_or_404, render - from teleforma.models.appointment import AppointmentPeriod, Appointment + from teleforma.models.appointment import AppointmentPeriod, Appointment, AppointmentDay, AppointmentSlot + from teleforma.views.core import get_periods + + from django.http import HttpResponse, HttpResponseRedirect + from django.core.urlresolvers import reverse, reverse_lazy + from django.db import IntegrityError class Appointments(View): template_name = 'teleforma/appointments.html' + def check_rights(self, user, period_id): + if not user.is_authenticated(): + return HttpResponseRedirect(reverse('teleforma-login')) + student = user.student.all().count() + if not student: + return HttpResponse('Unauthorized', status=401) + periods = [ int(p.id) for p in get_periods(user) ] + if not int(period_id) in periods: + return HttpResponse('Unauthorized', status=401) + return + - def render(self, request, period_id, msg = None): + def render(self, request, period_id): + # Ensure user is logged in, a student, and has access to current period + user = request.user + + # Get info ap_periods = [] for ap_period in AppointmentPeriod.objects.filter(period=period_id).order_by('id'): ap_periods.append({ @@@ -21,42 -38,69 +41,88 @@@ }) # for ap_period in ap_periods: # appointments[ap_period.id] = ap_period.get_appointments(request.user) - return render(request, self.template_name, {'ap_periods': ap_periods, - 'msg': msg}) + return render(request, self.template_name, {'ap_periods': ap_periods, 'period_id':period_id}) + def check_validity(self, user, slot_id, slot_nb, jury_id, day_id): + """ + Check if we can register to this exact slot + """ + day = get_object_or_404(AppointmentDay, id = day_id) + + # Check the period is open + if not day.appointment_period.is_open: + return u"La période d'inscription n'est pas ouverte" + # Check we are least delay (ie, 48h) before the date + if not day.can_book_today(): + delay = day.book_delay + return u"Vous devez réserver au moins %d jours ouvrés à l'avance" % delay + # Check if this jury is open + jurys = day.available_jurys + if not jury_id in [ j.id for j in jurys ]: + return u"Ce jury n'est pas ouvert" + # Check if this slot is empty + if Appointment.objects.filter(slot_id = slot_id, slot_nb = slot_nb, + jury_id = jury_id).exists(): + return u"Ce créneau n'est plus disponible" + # Check if this slot exists + slot = get_object_or_404(AppointmentSlot, id = slot_id) + if slot_nb >= slot.nb: + return u"Ce créneau n'existe pas" + # Check we don't have another appointment on this period + if day.appointment_period.get_appointment(user): + return u"Vous avez déjà un rendez-vous" + def post(self, request, period_id): + + user = request.user + rights = self.check_rights(user, period_id) + if rights: + return rights + slot_nb = int(request.POST.get('slot_nb')) slot_id = int(request.POST.get('slot')) jury_id = int(request.POST.get('jury')) day_id = int(request.POST.get('day')) - # TODO : verifier que l'appointment est libre, sinon rediriger vers une page d'erreur - ap = Appointment() - ap.slot_nb = slot_nb - ap.slot_id = slot_id - ap.jury_id = jury_id - ap.day_id = day_id - ap.student = request.user - ap.save() - messages.add_message(request, messages.INFO, "Votre réservation a bien été prise en compte.") + msg = self.check_validity(user, slot_id, slot_nb, jury_id, day_id) + + if not msg: + ap = Appointment() + ap.slot_nb = slot_nb + ap.slot_id = slot_id + ap.jury_id = jury_id + ap.day_id = day_id + ap.student = user + try: + ap.save() + except IntegrityError: + # Duplicate appointment caught by the db + msg = u"Ce créneau n'est plus disponible" - return self.render(request, period_id, msg = msg) ++ messages.add_message(request, messages.INFO, "Votre réservation a bien été prise en compte.") ++ else: ++ messages.add_message(request, messages.ERROR, msg) + return self.render(request, period_id) def get(self, request, period_id): + rights = self.check_rights(request.user, period_id) + if rights: + return rights return self.render(request, period_id) + + +def cancel_appointment(request): + period_id = request.POST['period_id'] + appointment_id = request.POST['appointment_id'] + try: + app = Appointment.objects.get(id=appointment_id) + except Appointment.DoesNotExist: + pass + + if app.student != request.user: + return HttpResponse('Unauthorized', status=401) + + app.delete() + messages.add_message(request, messages.INFO, 'Votre réservation a été annulé.') + return redirect('teleforma-appointments', period_id=period_id) +