Commit be0505a4 authored by Tangui's avatar Tangui

Merge branch 'master' of git.regardscitoyens.org:regardscitoyens/irfm

parents c050adba 78777808
...@@ -17,6 +17,7 @@ from .models import db ...@@ -17,6 +17,7 @@ from .models import db
from .tools.files import generer_demandes as generer_demandes_ from .tools.files import generer_demandes as generer_demandes_
from .tools.mails import (envoyer_emails as envoyer_emails_, from .tools.mails import (envoyer_emails as envoyer_emails_,
envoyer_relances as envoyer_relances_,
mailing_lists as mailing_lists_) mailing_lists as mailing_lists_)
from .tools.procedure import fix_procedure as fix_procedure_ from .tools.procedure import fix_procedure as fix_procedure_
from .tools.text import hash_password from .tools.text import hash_password
...@@ -60,6 +61,14 @@ def envoyer_emails(envoyer=False): ...@@ -60,6 +61,14 @@ def envoyer_emails(envoyer=False):
print('Aucun parlementaire sans adresse mail :)') print('Aucun parlementaire sans adresse mail :)')
@manager.command
@manager.option('--envoyer', action='store_true')
def envoyer_relances(envoyer=False):
"""Envoie des e-mails de relance"""
app.config.update(SQLALCHEMY_ECHO=False)
envoyer_relances_(app, envoyer)
@manager.command @manager.command
def mailing_lists(): def mailing_lists():
"""Affiche les abonnés aux mailing lists""" """Affiche les abonnés aux mailing lists"""
......
...@@ -9,6 +9,10 @@ from ..models import Action, Parlementaire, db ...@@ -9,6 +9,10 @@ from ..models import Action, Parlementaire, db
from ..models.constants import ETAPE_ENVOYE from ..models.constants import ETAPE_ENVOYE
class SuiviInvalide(Exception):
pass
class LaPosteImporter(BaseImporter): class LaPosteImporter(BaseImporter):
URL = 'http://www.part.csuivi.courrier.laposte.fr/suivi/index?id={}' URL = 'http://www.part.csuivi.courrier.laposte.fr/suivi/index?id={}'
...@@ -35,8 +39,11 @@ class LaPosteImporter(BaseImporter): ...@@ -35,8 +39,11 @@ class LaPosteImporter(BaseImporter):
return None return None
ident = ident[0] ident = ident[0]
if ident.text.strip().startswith('Aucun '): idtxt = ident.text.strip()
if idtxt.startswith('Aucun '):
return None return None
elif idtxt.startswith('L\'identifiant saisi'):
raise SuiviInvalide()
produit = self._next_el_sibling(ident) produit = self._next_el_sibling(ident)
date = self._next_el_sibling(produit) date = self._next_el_sibling(produit)
...@@ -50,8 +57,12 @@ class LaPosteImporter(BaseImporter): ...@@ -50,8 +57,12 @@ class LaPosteImporter(BaseImporter):
def import_suivi(self, suivi): def import_suivi(self, suivi):
if suivi not in self.cache: if suivi not in self.cache:
statut = self._import_suivi(suivi) try:
self.info('SUIVI %s => %s' % (suivi, statut)) statut = self._import_suivi(suivi)
self.info('SUIVI %s => %s' % (suivi, statut))
except SuiviInvalide:
self.error('INVALIDE %s' % suivi)
statut = 'Suivi invalide !'
self.cache[suivi] = statut self.cache[suivi] = statut
return self.cache[suivi] return self.cache[suivi]
......
...@@ -15,28 +15,14 @@ while _m < 1: ...@@ -15,28 +15,14 @@ while _m < 1:
DEBUT_RELEVES = datetime.date(_y, _m, DEBUT_ACTION.day) DEBUT_RELEVES = datetime.date(_y, _m, DEBUT_ACTION.day)
# Délais pour la relance de citoyens en jours
DELAI_RELANCE = 7
DELAI_REPONSE = 2
# # Etapes
# Lors de la modification de ces énumérations, penser à créer une migration DB
# pour mettre à jour les types ENUM correspondants en base de données.
#
CHAMBRES = { ETAPE_DOC_PUBLIE = -31
'AN': 'Assemblée nationale', ETAPE_DOC_MASQUE = -30
'SEN': 'Sénat',
}
SEXES = {
'F': 'Femme',
'H': 'Homme',
}
#
# Lors de la modification de cette énumération, relancer l'import des étapes.
# L'ordre est utilisé comme clé primaire lors de cet import.
#
ETAPE_DOCUMENT = -30
ETAPE_COM_PUBLIE = -21 ETAPE_COM_PUBLIE = -21
ETAPE_COM_A_MODERER = -20 ETAPE_COM_A_MODERER = -20
ETAPE_COURRIEL = -10 ETAPE_COURRIEL = -10
...@@ -50,12 +36,23 @@ ETAPE_REPONSE_NEGATIVE = 50 ...@@ -50,12 +36,23 @@ ETAPE_REPONSE_NEGATIVE = 50
ETAPES = [ ETAPES = [
{ {
'ordre': ETAPE_DOCUMENT, 'ordre': ETAPE_DOC_PUBLIE,
'label': 'Document', 'label': 'Document',
'description': """ 'description': """
Un document nous a été transmis par le parlementaire. Un document nous a été transmis par le parlementaire.
""", """,
'couleur': '#88dd88', 'couleur': '#33aa33',
'icone': 'paperclip',
'hidden': False,
'alerte': False,
},
{
'ordre': ETAPE_DOC_MASQUE,
'label': 'Document (non publié)',
'description': """
Un document nous a été transmis par le parlementaire.
""",
'couleur': '#ccaa66',
'icone': 'paperclip', 'icone': 'paperclip',
'hidden': True, 'hidden': True,
'alerte': False, 'alerte': False,
...@@ -182,3 +179,19 @@ ETAPES = [ ...@@ -182,3 +179,19 @@ ETAPES = [
] ]
ETAPES_BY_ORDRE = {e['ordre']: e for e in ETAPES} ETAPES_BY_ORDRE = {e['ordre']: e for e in ETAPES}
#
# Lors de la modification de ces énumérations, penser à créer une migration DB
# pour mettre à jour les types ENUM correspondants en base de données.
#
CHAMBRES = {
'AN': 'Assemblée nationale',
'SEN': 'Sénat',
}
SEXES = {
'F': 'Femme',
'H': 'Homme',
}
# -*- coding: utf-8 -*-
from sqlalchemy.sql.expression import case, func
from .constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER, ETAPE_ENVOYE,
ETAPE_NA, ETAPES)
from .database import db
from .parlementaire import Parlementaire
from .procedure import Action
def etat_courriers():
"""
Renvoie les données pour constituer un histogramme des états des courriers.
"""
_categories = [
{'etats': [''], 'label': 'Inconnu'},
{'etats': ['Pris en charge', 'En cours de traitement'],
'label': 'Pris en charge'},
{'etats': ['Pli présenté', 'En attente de seconde présentation'],
'label': 'Présenté'},
{'etats': ['Attend d\'être retiré au guichet'], 'label': 'Au guichet'},
{'etats': ['Distribué'], 'label': 'Distribué'}
]
# Extrait "Distribué" de "1X23456: Distribué (01/02/2017)"
expr = func.split_part(
func.split_part(
Action.suivi, ':', 2),
' (', 1
)
data = {item.etat: item.nb
for item in db.session.query(expr.label('etat'),
func.count(1).label('nb'))
.filter(Action.etape == ETAPE_ENVOYE)
.group_by(expr)
.all()}
return [(c['label'], sum([data.get(e, 0) for e in c['etats']]))
for c in _categories]
def par_departement():
"""
Renvoie chaque département avec le nombre total de parlementaires, le
nombre à chaque étape, le nombre >= pris en charge, le nombre >= envoyé
"""
# Comptage des parlementaires par département...
dept_qs = db.session \
.query(Parlementaire.num_deptmt,
func.count(Parlementaire.id).label('total'))
# ...et par étape
dept_qs = dept_qs.add_columns(*[
func.sum(case([(Parlementaire.etape == e['ordre'], 1)], else_=0))
.label('nb_etape_%s' % e['ordre'])
for e in ETAPES
])
# ...et qui sont dans une étape >= pris en charge
dept_qs = dept_qs.add_columns(
func.sum(case([(Parlementaire.etape >= ETAPE_A_CONFIRMER, 1)],
else_=0)).label('nb_prisencharge'),
func.sum(case([(Parlementaire.etape >= ETAPE_ENVOYE, 1)],
else_=0)).label('nb_envoyes')
)
return dept_qs.group_by(Parlementaire.num_deptmt) \
.order_by(Parlementaire.num_deptmt) \
.all()
def par_etape():
"""
Renvoie les étapes avec le nombre de parlementaires par étape
"""
count = func.count(Parlementaire.id)
return db.session.query(Parlementaire.etape, count.label('nb')) \
.filter(Parlementaire.etape > ETAPE_NA) \
.group_by(Parlementaire.etape) \
.order_by(Parlementaire.etape) \
.having(count > 0) \
.all()
def random_parl():
"""
Renvoie un parlementaire au hasard parmi ceux à l'état "À envoyer", ou si
aucun n'est disponible parmi ceux concernés par l'opération
"""
parl = Parlementaire.query \
.filter(Parlementaire.etape == ETAPE_A_ENVOYER) \
.order_by(func.random()) \
.first()
if not parl:
parl = Parlementaire.query \
.filter(Parlementaire.etape > ETAPE_NA) \
.order_by(func.random()) \
.first()
return parl
...@@ -10,7 +10,8 @@ from sqlalchemy.orm import joinedload ...@@ -10,7 +10,8 @@ from sqlalchemy.orm import joinedload
from ..models import Action, Parlementaire, User, db from ..models import Action, Parlementaire, User, db
from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER, from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER,
ETAPES_BY_ORDRE, ETAPE_COM_A_MODERER, ETAPES_BY_ORDRE, ETAPE_COM_A_MODERER,
ETAPE_COM_PUBLIE, ETAPE_DOCUMENT) ETAPE_COM_PUBLIE, ETAPE_DOC_MASQUE,
ETAPE_DOC_PUBLIE)
from ..tools.files import EXTENSIONS, handle_upload from ..tools.files import EXTENSIONS, handle_upload
from ..tools.mails import envoyer_alerte from ..tools.mails import envoyer_alerte
...@@ -103,12 +104,20 @@ def setup_routes(app): ...@@ -103,12 +104,20 @@ def setup_routes(app):
@require_admin @require_admin
def admin_publish(id): def admin_publish(id):
action = Action.query \ action = Action.query \
.filter(Action.etape == ETAPE_COM_A_MODERER) \ .filter(Action.etape.in_([ETAPE_COM_A_MODERER,
ETAPE_DOC_MASQUE,
ETAPE_DOC_PUBLIE])) \
.filter(Action.id == id) \ .filter(Action.id == id) \
.first() .first()
if action: if action:
action.etape = ETAPE_COM_PUBLIE if action.etape == ETAPE_COM_A_MODERER:
action.etape = ETAPE_COM_PUBLIE
elif action.etape == ETAPE_DOC_PUBLIE:
action.etape = ETAPE_DOC_MASQUE
elif action.etape == ETAPE_DOC_MASQUE:
action.etape = ETAPE_DOC_PUBLIE
db.session.commit() db.session.commit()
return redirect_back() return redirect_back()
...@@ -147,7 +156,7 @@ def setup_routes(app): ...@@ -147,7 +156,7 @@ def setup_routes(app):
return redirect_back(error=msg, return redirect_back(error=msg,
fallback=url_for('parlementaire', id=id_parl)) fallback=url_for('parlementaire', id=id_parl))
if etape == ETAPE_DOCUMENT: if etape in (ETAPE_DOC_MASQUE, ETAPE_DOC_PUBLIE):
prefix = 'document' prefix = 'document'
else: else:
prefix = 'etape-%s' % etape prefix = 'etape-%s' % etape
......
...@@ -4,12 +4,13 @@ from datetime import datetime ...@@ -4,12 +4,13 @@ from datetime import datetime
from flask import session, url_for from flask import session, url_for
from ..models import Action, Parlementaire from ..models import Action, Parlementaire, User
from ..models.constants import (CHAMBRES, ETAPES, ETAPES_BY_ORDRE, from ..models.constants import (CHAMBRES, ETAPES, ETAPES_BY_ORDRE,
ETAPE_AR_RECU, ETAPE_A_CONFIRMER, ETAPE_AR_RECU, ETAPE_A_CONFIRMER,
ETAPE_A_ENVOYER, ETAPE_COM_A_MODERER, ETAPE_A_ENVOYER, ETAPE_COM_A_MODERER,
ETAPE_COM_PUBLIE, ETAPE_COURRIEL, ETAPE_ENVOYE, ETAPE_COM_PUBLIE, ETAPE_COURRIEL,
ETAPE_NA, ETAPE_REPONSE_NEGATIVE, ETAPE_DOC_MASQUE, ETAPE_DOC_PUBLIE,
ETAPE_ENVOYE, ETAPE_NA, ETAPE_REPONSE_NEGATIVE,
ETAPE_REPONSE_POSITIVE) ETAPE_REPONSE_POSITIVE)
...@@ -108,25 +109,29 @@ def setup(app): ...@@ -108,25 +109,29 @@ def setup(app):
.filter(Parlementaire.etape == ETAPE_A_CONFIRMER).count() .filter(Parlementaire.etape == ETAPE_A_CONFIRMER).count()
if nb_aconfirmer > 0: if nb_aconfirmer > 0:
badge = ' <span class="badge">%s</span>' % nb_aconfirmer
menu += [ menu += [
{ {
'url': url_for('admin_en_attente'), 'url': url_for('admin_en_attente'),
'label': '<span class="admin">À confirmer (%s)</span>' 'label': '<span class="admin">À confirmer</span> %s'
% nb_aconfirmer, % badge,
'endpoint': 'admin_en_attente' 'endpoint': 'admin_en_attente'
} }
] ]
nb_moderer = Action.query \ nb_moderer = Action.query \
.join(Action.user) \
.filter(Action.etape == ETAPE_COM_A_MODERER) \ .filter(Action.etape == ETAPE_COM_A_MODERER) \
.filter(User.nick != '!rc') \
.count() .count()
if nb_moderer > 0: if nb_moderer > 0:
badge = ' <span class="badge">%s</span>' % nb_moderer
menu += [ menu += [
{ {
'url': url_for('admin_commentaires'), 'url': url_for('admin_commentaires'),
'label': '<span class="admin">À modérer (%s)</span>' 'label': '<span class="admin">À modérer</span> %s'
% nb_moderer, % badge,
'endpoint': 'admin_commentaires' 'endpoint': 'admin_commentaires'
} }
] ]
...@@ -141,6 +146,8 @@ def setup(app): ...@@ -141,6 +146,8 @@ def setup(app):
'ordres': { 'ordres': {
'ETAPE_COM_PUBLIE': ETAPE_COM_PUBLIE, 'ETAPE_COM_PUBLIE': ETAPE_COM_PUBLIE,
'ETAPE_COM_A_MODERER': ETAPE_COM_A_MODERER, 'ETAPE_COM_A_MODERER': ETAPE_COM_A_MODERER,
'ETAPE_DOC_MASQUE': ETAPE_DOC_MASQUE,
'ETAPE_DOC_PUBLIE': ETAPE_DOC_PUBLIE,
'ETAPE_COURRIEL': ETAPE_COURRIEL, 'ETAPE_COURRIEL': ETAPE_COURRIEL,
'ETAPE_NA': ETAPE_NA, 'ETAPE_NA': ETAPE_NA,
'ETAPE_A_ENVOYER': ETAPE_A_ENVOYER, 'ETAPE_A_ENVOYER': ETAPE_A_ENVOYER,
......
...@@ -20,8 +20,8 @@ def setup_routes(app): ...@@ -20,8 +20,8 @@ def setup_routes(app):
if not os.path.exists(uploads_root): if not os.path.exists(uploads_root):
os.mkdir(uploads_root) os.mkdir(uploads_root)
@app.route('/parlementaire/<id>/demande/<mode>', endpoint='demande_pdf') @app.route('/parlementaire/<id>/demande', endpoint='demande_pdf')
def demande_pdf(id, mode='download'): def demande_pdf(id):
parl = Parlementaire.query.filter_by(id=id).first() parl = Parlementaire.query.filter_by(id=id).first()
if not parl: if not parl:
...@@ -30,6 +30,16 @@ def setup_routes(app): ...@@ -30,6 +30,16 @@ def setup_routes(app):
filename = generer_demande(parl, files_root) filename = generer_demande(parl, files_root)
return redirect(url_for('get_file', filename=filename)) return redirect(url_for('get_file', filename=filename))
@app.route('/parlementaire/<id>/demande_png', endpoint='demande_png')
def demande_png(id):
parl = Parlementaire.query.filter_by(id=id).first()
if not parl:
return not_found()
filename = '%s.png' % generer_demande(parl, files_root)[:-4]
return redirect(url_for('get_file', filename=filename))
@app.route('/parlementaire/<id>/preuve-envoi', endpoint='preuve_envoi') @app.route('/parlementaire/<id>/preuve-envoi', endpoint='preuve_envoi')
def preuve_envoi(id): def preuve_envoi(id):
act = Action.query.filter(Action.etape == ETAPE_ENVOYE) \ act = Action.query.filter(Action.etape == ETAPE_ENVOYE) \
......
...@@ -2,73 +2,49 @@ ...@@ -2,73 +2,49 @@
from flask import render_template from flask import render_template
from sqlalchemy.sql.expression import case, func from ..models.constants import ETAPES_BY_ORDRE
from ..models.queries import (etat_courriers, par_etape, par_departement,
from ..models import Parlementaire, db random_parl)
from ..models.constants import (ETAPES, ETAPES_BY_ORDRE, ETAPE_A_CONFIRMER,
ETAPE_A_ENVOYER, ETAPE_ENVOYE, ETAPE_NA)
def setup_routes(app): def setup_routes(app):
@app.route('/', endpoint='home') @app.route('/', endpoint='home')
def home(): def home():
# Un parlementaire à l'étape "à envoyer" au hasard # Données camembert
parl = Parlementaire.query \
.filter(Parlementaire.etape == ETAPE_A_ENVOYER) \
.order_by(func.random()) \
.first()
# Toutes les étapes avec le nombre de parlementaires à cette étape
etapes_qs = db.session \
.query(Parlementaire.etape,
func.count(Parlementaire.id).label('nb')) \
.filter(Parlementaire.etape > ETAPE_NA) \
.group_by(Parlementaire.etape) \
.order_by(Parlementaire.etape) \
.all()
# Comptage des parlementaires par département... etapes_qs = par_etape()
dept_qs = db.session \
.query(Parlementaire.num_deptmt,
func.count(Parlementaire.id).label('total'))
# ...et par étape def each_etape(getter):
dept_qs = dept_qs.add_columns(*[ return [getter(e) for e in etapes_qs]
func.sum(case([(Parlementaire.etape == e['ordre'], 1)], else_=0))
.label('nb_etape_%s' % e['ordre'])
for e in ETAPES
])
# ...et qui sont dans une étape >= pris en charge def key_each_etape(key):
dept_qs = dept_qs.add_columns( return each_etape(lambda e: ETAPES_BY_ORDRE[e.etape][key])
func.sum(case([(Parlementaire.etape >= ETAPE_A_CONFIRMER, 1)],
else_=0)).label('nb_prisencharge'),
func.sum(case([(Parlementaire.etape >= ETAPE_ENVOYE, 1)],
else_=0)).label('nb_envoyes')
)
dept_qs = dept_qs.group_by(Parlementaire.num_deptmt) \ etapes_data = {
.order_by(Parlementaire.num_deptmt) \ 'labels': key_each_etape('label'),
.all() 'datasets': [{
'data': each_etape(lambda e: e.nb),
'backgroundColor': key_each_etape('couleur'),
'hoverBackgroundColor': key_each_etape('couleur'),
'borderWidth': 0
}]
}
def for_nz(getter): # Données histogramme
return [getter(e) for e in etapes_qs if e.nb > 0]
def key_for_nz(key): etats = etat_courriers()
return for_nz(lambda e: ETAPES_BY_ORDRE[e.etape][key]) histo_data = {
'labels': [etat for etat, nb in etats],
'datasets': [{
'data': [nb for etat, nb in etats]
}]
}
return render_template( return render_template(
'index.html.j2', 'index.html.j2',
parlementaire=parl, parlementaire=random_parl(),
etapes_data={ etapes_data=etapes_data,
'labels': key_for_nz('label'), histo_data=histo_data,
'datasets': [{ departements=par_departement()
'data': for_nz(lambda e: e.nb),
'backgroundColor': key_for_nz('couleur'),
'hoverBackgroundColor': key_for_nz('couleur'),
'borderWidth': for_nz(lambda e: 0)
}]
},
departements=dept_qs
) )
...@@ -8,15 +8,17 @@ from flask import (flash, redirect, render_template, request, session, url_for) ...@@ -8,15 +8,17 @@ from flask import (flash, redirect, render_template, request, session, url_for)
from flask_mail import Mail, Message from flask_mail import Mail, Message
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
from ..models import Action, Parlementaire, User, db from ..models import Action, Parlementaire, User, db
from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER, from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER,
ETAPE_COM_A_MODERER, ETAPE_COM_PUBLIE, ETAPE_COM_A_MODERER, ETAPE_COM_PUBLIE,
ETAPE_ENVOYE, ETAPE_NA) ETAPE_ENVOYE)
from ..models.queries import random_parl
from ..tools.files import generer_demande, handle_upload from ..tools.files import generer_demande, handle_upload
from ..tools.routing import not_found, redirect_back, remote_addr, require_user from ..tools.routing import (can_login_from_token, not_found, redirect_back,
from ..tools.text import check_suivi, slugify remote_addr, require_user)
from ..tools.text import check_suivi, create_usertoken as token, slugify
def pris_en_charge(parl, force=False): def pris_en_charge(parl, force=False):
...@@ -46,17 +48,7 @@ def setup_routes(app): ...@@ -46,17 +48,7 @@ def setup_routes(app):
@app.route('/hasard', endpoint='hasard') @app.route('/hasard', endpoint='hasard')
def hasard(): def hasard():
parl = Parlementaire.query \ return redirect(url_for('parlementaire', id=random_parl().id))
.filter(Parlementaire.etape == ETAPE_A_ENVOYER) \
.order_by(func.random()) \
.first()
if not parl:
parl = Parlementaire.query \
.filter(Parlementaire.etape > ETAPE_NA) \
.order_by(func.random()) \
.first()
return redirect(url_for('parlementaire', id=parl.id))
@app.route('/parlementaires', endpoint='parlementaires') @app.route('/parlementaires', endpoint='parlementaires')
def parlementaires(): def parlementaires():
...@@ -71,6 +63,7 @@ def setup_routes(app): ...@@ -71,6 +63,7 @@ def setup_routes(app):
) )
@app.route('/parlementaires/<id>', endpoint='parlementaire') @app.route('/parlementaires/<id>', endpoint='parlementaire')
@can_login_from_token
def parlementaire(id): def parlementaire(id):
parl = Parlementaire.query \ parl = Parlementaire.query \
.filter_by(id=id) \ .filter_by(id=id) \
...@@ -143,6 +136,8 @@ def setup_routes(app): ...@@ -143,6 +136,8 @@ def setup_routes(app):
subject = 'Transparence IRFM - Envoi d\'une demande de documents' subject = 'Transparence IRFM - Envoi d\'une demande de documents'
body = render_template('courriers/mail_prise_en_charge.txt.j2', body = render_template('courriers/mail_prise_en_charge.txt.j2',
token=token(session['user']['id'],
app.config['SECRET_KEY']),
parlementaire=parl) parlementaire=parl)
msg = Message(subject=subject, body=body, msg = Message(subject=subject, body=body,
sender=('Regards Citoyens', sender=('Regards Citoyens',
...@@ -152,6 +147,9 @@ def setup_routes(app): ...@@ -152,6 +147,9 @@ def setup_routes(app):
with open(os.path.join(files_root, filename), 'rb') as f: with open(os.path.join(files_root, filename), 'rb') as f:
msg.attach(filename, 'application/pdf', f.read()) msg.attach(filename, 'application/pdf', f.read())
if app.config['MAIL_SUPPRESS_SEND']:
print(msg)
mail.send(msg) mail.send(msg)
return redirect(url_for('parlementaire', id=id)) return redirect(url_for('parlementaire', id=id))
...@@ -213,7 +211,8 @@ def setup_routes(app): ...@@ -213,7 +211,8 @@ def setup_routes(app):
return redirect_back(error=msg, return redirect_back(error=msg,
fallback=url_for('parlementaire', id=id)) fallback=url_for('parlementaire', id=id))
if not check_suivi(request.form['suivi']): suivi = check_suivi(request.form['suivi'])
if not suivi:
msg = 'Veuillez indiquer un numéro de suivi valide' msg = 'Veuillez indiquer un numéro de suivi valide'
return redirect_back(error=msg, return redirect_back(error=msg,
fallback=url_for('parlementaire', id=id)) fallback=url_for('parlementaire', id=id))
...@@ -236,7 +235,7 @@ def setup_routes(app): ...@@ -236,7 +235,7 @@ def setup_routes(app):
parlementaire=parl, parlementaire=parl,
etape=parl.etape, etape=parl.etape,
attachment=filename, attachment=filename,
suivi=request.form['suivi'].upper() suivi=suivi
) )
db.session.add(action) db.session.add(action)
......
...@@ -8,7 +8,8 @@ from ..models import Action, Parlementaire, User, db ...@@ -8,7 +8,8 @@ from ..models import Action, Parlementaire, User, db
from ..models.constants import ETAPE_A_CONFIRMER, ETAPE_ENVOYE from ..models.constants import ETAPE_A_CONFIRMER, ETAPE_ENVOYE
from ..tools.routing import not_found, redirect_back, require_user from ..tools.routing import not_found, redirect_back, require_user
from ..tools.text import check_email, check_password, sanitize_hard