Commit 98da0282 authored by Nicolas Joyard's avatar Nicolas Joyard

Regroupement requetes graphes/stats

parent a800fbe4
# -*- 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.
"""
_etats = [
'Inconnu',
'Pris en charge',
'En cours de traitement',
'En attente de seconde présentation',
'Pli présenté',
'Attend d\'être retiré au guichet',
'Distribué',
]
# Extrait "Distribué" de "1X23456: Distribué (01/02/2017)"
expr = func.split_part(
func.split_part(
Action.suivi, ':', 2),
' (', 1
)
data = {item.etat if len(item.etat) else 'Inconnu': 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 [(etat, data.get(etat, 0)) for etat in _etats]
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
......@@ -2,73 +2,35 @@
from flask import render_template
from sqlalchemy.sql.expression import case, func
from ..models import Parlementaire, db
from ..models.constants import (ETAPES, ETAPES_BY_ORDRE, ETAPE_A_CONFIRMER,
ETAPE_A_ENVOYER, ETAPE_ENVOYE, ETAPE_NA)
from ..models.constants import ETAPES_BY_ORDRE
from ..models.queries import par_etape, par_departement, random_parl
def setup_routes(app):
@app.route('/', endpoint='home')
def home():
# Un parlementaire à l'étape "à envoyer" au hasard
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...
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')
)
etapes_qs = par_etape()
dept_qs = dept_qs.group_by(Parlementaire.num_deptmt) \
.order_by(Parlementaire.num_deptmt) \
.all()
def each_etape(getter):
return [getter(e) for e in etapes_qs]
def for_nz(getter):
return [getter(e) for e in etapes_qs if e.nb > 0]
def key_each_etape(key):
return each_etape(lambda e: ETAPES_BY_ORDRE[e.etape][key])
def key_for_nz(key):
return for_nz(lambda e: ETAPES_BY_ORDRE[e.etape][key])
etapes_data = {
'labels': key_each_etape('label'),
'datasets': [{
'data': each_etape(lambda e: e.nb),
'backgroundColor': key_each_etape('couleur'),
'hoverBackgroundColor': key_each_etape('couleur'),
'borderWidth': each_etape(lambda e: 0)
}]
}
return render_template(
'index.html.j2',
parlementaire=parl,
etapes_data={
'labels': key_for_nz('label'),
'datasets': [{
'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
parlementaire=random_parl(),
etapes_data=etapes_data,
departements=par_departement()
)
......@@ -8,12 +8,13 @@ from flask import (flash, redirect, render_template, request, session, url_for)
from flask_mail import Mail, Message
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
from ..models import Action, Parlementaire, User, db
from ..models.constants import (ETAPE_A_CONFIRMER, ETAPE_A_ENVOYER,
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.routing import (can_login_from_token, not_found, redirect_back,
remote_addr, require_user)
......@@ -47,17 +48,7 @@ def setup_routes(app):
@app.route('/hasard', endpoint='hasard')
def hasard():
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 redirect(url_for('parlementaire', id=parl.id))
return redirect(url_for('parlementaire', id=random_parl().id))
@app.route('/parlementaires', endpoint='parlementaires')
def parlementaires():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment