예제 #1
0
def status(applicant_id, course_id):
    attendance = models.Attendance.query.get_or_404((applicant_id, course_id))
    form = forms.StatusForm()

    if form.validate_on_submit():
        try:
            attendance.graduation = form.get_graduation()
            attendance.payingdate = datetime.utcnow()
            attendance.waiting = form.waiting.data
            attendance.has_to_pay = form.has_to_pay.data
            attendance.applicant.discounted = form.discounted.data
            attendance.paidbycash = form.paidbycash.data
            attendance.amountpaid = form.amountpaid.data
            db.session.commit()
            flash('Der Status wurde aktualisiert', 'success')
        except Exception as e:
            db.session.rollback()
            flash('Der Status konnte nicht aktualisiert werden: {0}'.format(e), 'negative')
            return dict(form=form, attendance=attendance)

        if form.notify_change.data:
            try:
                course = attendance.course
                applicant = attendance.applicant
                tasks.send_quick.delay(generate_status_mail(applicant, course))
                flash('Mail erfolgreich verschickt', 'success')
            except (AssertionError, socket.error, ConnectionError) as e:
                flash('Mail konnte nicht verschickt werden: {0}'.format(e), 'negative')

    form.populate(attendance)
    return dict(form=form, attendance=attendance)
예제 #2
0
def add_attendance(applicant_id, course_id, notify):
    applicant = models.Applicant.query.get_or_404(applicant_id)
    course = models.Course.query.get_or_404(course_id)

    if applicant.in_course(course) or applicant.active_in_parallel_course(course):
        flash('Der Teilnehmer ist bereits im Kurs oder nimmt aktiv an einem Parallelkurs teil', 'negative')
        return redirect(url_for('applicant', id=applicant_id))

    try:
        applicant.add_course_attendance(course, None, False, applicant.has_to_pay())
        db.session.commit()
        flash('Der Teilnehmer wurde in den Kurs eingetragen. Bitte jetzt Status setzen und überprüfen.', 'success')

        if not course.is_allowed(applicant):
            flash(
                'Der Teilnehmer hat eigentlich nicht die entsprechenden Sprachtest-Ergebnisse.'
                'Teilnehmer wurde trotzdem eingetragen.',
                'warning'
            )

    except Exception as e:
        db.session.rollback()
        flash('Der Teilnehmer konnte nicht für den Kurs eingetragen werden: {0}'.format(e), 'negative')
        return redirect(url_for('applicant', id=applicant_id))

    if notify:
        try:
            tasks.send_slow.delay(generate_status_mail(applicant, course, restock=True))
            flash('Mail erfolgreich verschickt', 'success')
        except (AssertionError, socket.error, ConnectionError) as e:
            flash('Mail konnte nicht verschickt werden: {0}'.format(e), 'negative')

    return redirect(url_for('status', applicant_id=applicant_id, course_id=course_id))
예제 #3
0
def send_mails(attendances):
    """Send mails to handled (successful or not) attendances."""
    try:
        for attendance, informed_before_now in attendances:
            # consider this a restock if we already send out a "no, sorry" mail
            restock = informed_before_now

            tasks.send_slow.delay(
                generate_status_mail(attendance.applicant, attendance.course, restock=restock),
            )

    except (AssertionError, socket.error, ConnectionError) as e:
        raise e
예제 #4
0
def remove_attendance(applicant, course, notify):
    success = applicant.remove_course_attendance(course)
    if success:
        if applicant.is_student():
            active_courses = [a for a in applicant.attendances if not a.waiting]
            free_courses = [a for a in active_courses if not a.has_to_pay]
            if active_courses and not free_courses:
                active_courses[0].has_to_pay = False

    if notify and success:
        try:
            tasks.send_slow.delay(generate_status_mail(applicant, course))
            flash('Bestätigungsmail wurde versendet', 'success')
        except (AssertionError, socket.error, ConnectionError) as e:
            flash('Bestätigungsmail konnte nicht versendet werden: {0}'.format(e), 'negative')

    return success
예제 #5
0
def add_attendance(applicant, course, notify):
    if applicant.in_course(course) or applicant.active_in_parallel_course(course):
        raise ValueError('Der Teilnehmer ist bereits im Kurs oder nimmt aktiv an einem Parallelkurs teil!', 'warning')

    applicant.add_course_attendance(course, None, False, applicant.has_to_pay())
    db.session.commit()

    if not course.is_allowed(applicant):
        flash(
            'Der Teilnehmer hat eigentlich nicht die entsprechenden Sprachtest-Ergebnisse. '
            'Teilnehmer wurde trotzdem eingetragen.',
            'warning'
        )

    if notify:
        try:
            tasks.send_slow.delay(generate_status_mail(applicant, course, restock=True))
            flash('Bestätigungsmail wurde versendet', 'success')
        except (AssertionError, socket.error, ConnectionError) as e:
            flash('Bestätigungsmail konnte nicht versendet werden: {0}'.format(e), 'negative')
예제 #6
0
def remove_attendance(applicant_id, course_id, notify):
    attendance = models.Attendance.query.get_or_404((applicant_id, course_id))
    applicant = attendance.applicant
    course = attendance.course

    try:
        attendance.applicant.remove_course_attendance(attendance.course)
        db.session.commit()
        flash('Der Bewerber wurde aus dem Kurs genommen', 'success')
    except Exception as e:
        db.session.rollback()
        flash('Der Bewerber konnte nicht aus dem Kurs genommen werden: {0}'.format(e), 'negative')
        return redirect(url_for('applicant', id=applicant_id))

    if notify:
        try:
            tasks.send_slow.delay(generate_status_mail(applicant, course))
            flash('Mail erfolgreich verschickt', 'success')
        except (AssertionError, socket.error, ConnectionError) as e:
            flash('Mail konnte nicht verschickt werden: {0}'.format(e), 'negative')

    return redirect(url_for('applicant', id=applicant_id))
예제 #7
0
def index():
    form = forms.SignupForm(show_all_courses=current_user.is_authenticated)
    time = datetime.utcnow()

    if current_user.is_authenticated:
        flash('Angemeldet: Vorzeitige Registrierung möglich. Falls unerwünscht, bitte abmelden.', 'success')

    if form.validate_on_submit():
        applicant = form.get_applicant()
        course = form.get_course()
        one_time_token = request.args.get('token', None)
        user_has_special_rights = current_user.is_authenticated and current_user.can_edit_course(course)

        # signup at all times only with token or privileged users
        preterm = applicant.mail and \
            one_time_token and \
            token.validate_once(
                token=one_time_token,
                payload_wanted=applicant.mail,
                namespace='preterm',
                db_model=models.Applicant,
                db_column=models.Applicant.mail
            )
        err = check_precondition_with_auth(
            course.language.is_open_for_signup(time) or preterm,
            'Bitte gedulden Sie sich, die Anmeldung für diese Sprache ist erst möglich in '
            '{0}!'.format(course.language.until_signup_fmt()),
            user_has_special_rights
        )
        err |= check_precondition_with_auth(
            course.is_allowed(applicant),
            'Sie haben nicht die vorausgesetzten Sprachtest-Ergebnisse um diesen Kurs zu wählen! '
            '(Hinweis: Der Datenabgleich mit Ilias erfolgt regelmäßig, jedoch nicht automatisch sondern manuell.)',  # 2*15m, just in case
            user_has_special_rights
        )
        err |= check_precondition_with_auth(
            not applicant.in_course(course) and not applicant.active_in_parallel_course(course),
            'Sie sind bereits für diesen Kurs oder einem Parallelkurs angemeldet!',
            user_has_special_rights
        )
        err |= check_precondition_with_auth(
            not applicant.over_limit(),
            'Sie haben das Limit an Bewerbungen bereits erreicht!',
            user_has_special_rights
        )
        err |= check_precondition_with_auth(
            not course.is_overbooked(),  # no transaction guarantees here, but overbooking is some sort of soft limit
            'Der Kurs ist hoffnungslos überbelegt. Darum werden keine Registrierungen mehr entgegengenommen!',
            user_has_special_rights
        )
        if err:
            return dict(form=form)

        # Run the final insert isolated in a transaction, with rollback semantics
        # As of 2015, we simply put everyone into the waiting list by default and then randomly insert, see #39
        try:
            waiting = not preterm
            informed_about_rejection = waiting and course.language.is_open_for_signup_fcfs(time)
            applicant.add_course_attendance(
                course,
                form.get_graduation(),
                waiting=waiting,
                has_to_pay=applicant.has_to_pay(),
                informed_about_rejection=informed_about_rejection
            )
            db.session.add(applicant)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            flash('Ihre Kurswahl konnte nicht registriert werden: {0}'.format(e), 'negative')
            return dict(form=form)

        # Preterm signups are in by default and management wants us to send mail immediately
        try:
            tasks.send_slow.delay(generate_status_mail(applicant, course, time))
        except (AssertionError, socket.error, ConnectionError) as e:
            flash('Eine Bestätigungsmail konnte nicht verschickt werden: {0}'.format(e), 'negative')

        # Finally redirect the user to an confirmation page, too
        return render_template('confirm.html', applicant=applicant, course=course)

    return dict(form=form)