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)
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))
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
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
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')
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))
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)