Filtres sur techniques, sous-traitance, innovant #65
This commit is contained in:
@@ -94,7 +94,6 @@ button:hover:not([disabled]) {
|
|||||||
padding: 28px 24px 0 24px;
|
padding: 28px 24px 0 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#header > * {
|
#header > * {
|
||||||
margin: 0 0 20px 0px;
|
margin: 0 0 20px 0px;
|
||||||
}
|
}
|
||||||
@@ -174,7 +173,6 @@ p.version > a {
|
|||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --- Dashboard inputs --- */
|
/* --- Dashboard inputs --- */
|
||||||
|
|
||||||
.Select--multi .Select-value {
|
.Select--multi .Select-value {
|
||||||
@@ -182,7 +180,7 @@ p.version > a {
|
|||||||
background-color: rgba(255, 240, 240, 0.4);
|
background-color: rgba(255, 240, 240, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#filters .col > * {
|
#filters .row > * {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+197
-208
@@ -1,5 +1,5 @@
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
|
|
||||||
import dash_bootstrap_components as dbc
|
import dash_bootstrap_components as dbc
|
||||||
import polars as pl
|
import polars as pl
|
||||||
@@ -33,6 +33,7 @@ from src.utils import (
|
|||||||
format_number,
|
format_number,
|
||||||
get_enum_values_as_dict,
|
get_enum_values_as_dict,
|
||||||
meta_content,
|
meta_content,
|
||||||
|
prepare_dashboard_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
name = "Observatoire"
|
name = "Observatoire"
|
||||||
@@ -60,78 +61,6 @@ options_departements = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _apply_filters(
|
|
||||||
lff: pl.LazyFrame,
|
|
||||||
year,
|
|
||||||
acheteur_id,
|
|
||||||
acheteur_categorie,
|
|
||||||
acheteur_departement_code,
|
|
||||||
titulaire_id,
|
|
||||||
titulaire_categorie,
|
|
||||||
titulaire_departement_code,
|
|
||||||
marche_type,
|
|
||||||
considerations_sociales,
|
|
||||||
considerations_environnementales,
|
|
||||||
montant_min=None,
|
|
||||||
montant_max=None,
|
|
||||||
) -> pl.LazyFrame:
|
|
||||||
if year:
|
|
||||||
lff = lff.filter(pl.col("dateNotification").dt.year() == int(year))
|
|
||||||
else:
|
|
||||||
lff = lff.filter(
|
|
||||||
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
|
||||||
)
|
|
||||||
|
|
||||||
if acheteur_id:
|
|
||||||
lff = lff.filter(pl.col("acheteur_id").str.contains(acheteur_id))
|
|
||||||
else:
|
|
||||||
if acheteur_categorie:
|
|
||||||
lff = lff.filter(pl.col("acheteur_categorie") == acheteur_categorie)
|
|
||||||
if acheteur_departement_code:
|
|
||||||
lff = lff.filter(
|
|
||||||
pl.col("acheteur_departement_code").is_in(acheteur_departement_code)
|
|
||||||
)
|
|
||||||
|
|
||||||
if titulaire_id:
|
|
||||||
lff = lff.filter(pl.col("titulaire_id").str.contains(titulaire_id))
|
|
||||||
else:
|
|
||||||
if titulaire_categorie:
|
|
||||||
lff = lff.filter(pl.col("titulaire_categorie") == titulaire_categorie)
|
|
||||||
if titulaire_departement_code:
|
|
||||||
lff = lff.filter(
|
|
||||||
pl.col("titulaire_departement_code").is_in(titulaire_departement_code)
|
|
||||||
)
|
|
||||||
|
|
||||||
if marche_type:
|
|
||||||
lff = lff.filter(pl.col("type") == marche_type)
|
|
||||||
|
|
||||||
if considerations_sociales:
|
|
||||||
lff = lff.filter(
|
|
||||||
pl.col("considerationsSociales")
|
|
||||||
.str.split(", ")
|
|
||||||
.list.set_intersection(considerations_sociales)
|
|
||||||
.list.len()
|
|
||||||
> 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if considerations_environnementales:
|
|
||||||
lff = lff.filter(
|
|
||||||
pl.col("considerationsEnvironnementales")
|
|
||||||
.str.split(", ")
|
|
||||||
.list.set_intersection(considerations_environnementales)
|
|
||||||
.list.len()
|
|
||||||
> 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if montant_min is not None:
|
|
||||||
lff = lff.filter(pl.col("montant") >= montant_min)
|
|
||||||
|
|
||||||
if montant_max is not None:
|
|
||||||
lff = lff.filter(pl.col("montant") <= montant_max)
|
|
||||||
|
|
||||||
return lff
|
|
||||||
|
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
dcc.Location(id="dashboard_url", refresh="callback-nav"),
|
dcc.Location(id="dashboard_url", refresh="callback-nav"),
|
||||||
dcc.Store(id="observatoire-filters", storage_type="local"),
|
dcc.Store(id="observatoire-filters", storage_type="local"),
|
||||||
@@ -181,6 +110,8 @@ Alors, on fait comment ?
|
|||||||
id="dashboard_year",
|
id="dashboard_year",
|
||||||
options=options_years,
|
options=options_years,
|
||||||
placeholder="12 derniers mois",
|
placeholder="12 derniers mois",
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -192,6 +123,8 @@ Alors, on fait comment ?
|
|||||||
placeholder="SIRET",
|
placeholder="SIRET",
|
||||||
debounce=True,
|
debounce=True,
|
||||||
style={"width": "100%"},
|
style={"width": "100%"},
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -203,6 +136,8 @@ Alors, on fait comment ?
|
|||||||
"acheteur_categorie"
|
"acheteur_categorie"
|
||||||
),
|
),
|
||||||
placeholder="Catégorie",
|
placeholder="Catégorie",
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -214,6 +149,8 @@ Alors, on fait comment ?
|
|||||||
multi=True,
|
multi=True,
|
||||||
placeholder="Département",
|
placeholder="Département",
|
||||||
options=options_departements,
|
options=options_departements,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -225,6 +162,8 @@ Alors, on fait comment ?
|
|||||||
placeholder="SIRET",
|
placeholder="SIRET",
|
||||||
debounce=True,
|
debounce=True,
|
||||||
style={"width": "100%"},
|
style={"width": "100%"},
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -236,6 +175,8 @@ Alors, on fait comment ?
|
|||||||
options=get_enum_values_as_dict(
|
options=get_enum_values_as_dict(
|
||||||
"titulaire_categorie"
|
"titulaire_categorie"
|
||||||
),
|
),
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -247,6 +188,8 @@ Alors, on fait comment ?
|
|||||||
multi=True,
|
multi=True,
|
||||||
placeholder="Département",
|
placeholder="Département",
|
||||||
options=options_departements,
|
options=options_departements,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -257,30 +200,8 @@ Alors, on fait comment ?
|
|||||||
id="dashboard_marche_type",
|
id="dashboard_marche_type",
|
||||||
placeholder="Type",
|
placeholder="Type",
|
||||||
options=get_enum_values_as_dict("type"),
|
options=get_enum_values_as_dict("type"),
|
||||||
),
|
persistence=True,
|
||||||
),
|
persistence_type="local",
|
||||||
),
|
|
||||||
dbc.Row(
|
|
||||||
dbc.Col(
|
|
||||||
dcc.Dropdown(
|
|
||||||
id="dashboard_marche_considerationsSociales",
|
|
||||||
placeholder="Considérations sociales",
|
|
||||||
options=get_enum_values_as_dict(
|
|
||||||
"considerationsSociales"
|
|
||||||
),
|
|
||||||
multi=True,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dbc.Row(
|
|
||||||
dbc.Col(
|
|
||||||
dcc.Dropdown(
|
|
||||||
id="dashboard_marche_considerationsEnvironnementales",
|
|
||||||
placeholder="Considérations environnementales",
|
|
||||||
multi=True,
|
|
||||||
options=get_enum_values_as_dict(
|
|
||||||
"considerationsEnvironnementales"
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -294,6 +215,8 @@ Alors, on fait comment ?
|
|||||||
min=0,
|
min=0,
|
||||||
debounce=True,
|
debounce=True,
|
||||||
style={"width": "100%"},
|
style={"width": "100%"},
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
width=6,
|
width=6,
|
||||||
),
|
),
|
||||||
@@ -305,11 +228,113 @@ Alors, on fait comment ?
|
|||||||
min=0,
|
min=0,
|
||||||
debounce=True,
|
debounce=True,
|
||||||
style={"width": "100%"},
|
style={"width": "100%"},
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
),
|
),
|
||||||
width=6,
|
width=6,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
dbc.Row(
|
||||||
|
dbc.Col(
|
||||||
|
dcc.Dropdown(
|
||||||
|
id="dashboard_marche_techniques",
|
||||||
|
placeholder="Techniques d'achat",
|
||||||
|
options=get_enum_values_as_dict(
|
||||||
|
"techniques"
|
||||||
|
),
|
||||||
|
multi=True,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dbc.Row(
|
||||||
|
[
|
||||||
|
dbc.Col("Sous-traitance :", lg=5),
|
||||||
|
dbc.Col(
|
||||||
|
dbc.RadioItems(
|
||||||
|
id="dashboard_marche_sousTraitanceDeclaree",
|
||||||
|
options=[
|
||||||
|
{
|
||||||
|
"label": "Tous",
|
||||||
|
"value": "all",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Oui",
|
||||||
|
"value": "oui",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Non",
|
||||||
|
"value": "non",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value="all",
|
||||||
|
inline=True,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
|
),
|
||||||
|
lg=7,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
dbc.Row(
|
||||||
|
[
|
||||||
|
dbc.Col("Marché innovant :", lg=5),
|
||||||
|
dbc.Col(
|
||||||
|
dbc.RadioItems(
|
||||||
|
id="dashboard_marche_innovant",
|
||||||
|
options=[
|
||||||
|
{
|
||||||
|
"label": "Tous",
|
||||||
|
"value": "all",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Oui",
|
||||||
|
"value": "oui",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Non",
|
||||||
|
"value": "non",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value="all",
|
||||||
|
inline=True,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
|
),
|
||||||
|
lg=7,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
dbc.Row(
|
||||||
|
dbc.Col(
|
||||||
|
dcc.Dropdown(
|
||||||
|
id="dashboard_marche_considerationsSociales",
|
||||||
|
placeholder="Considérations sociales",
|
||||||
|
options=get_enum_values_as_dict(
|
||||||
|
"considerationsSociales"
|
||||||
|
),
|
||||||
|
multi=True,
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dbc.Row(
|
||||||
|
dbc.Col(
|
||||||
|
dcc.Dropdown(
|
||||||
|
id="dashboard_marche_considerationsEnvironnementales",
|
||||||
|
placeholder="Considérations environnementales",
|
||||||
|
multi=True,
|
||||||
|
options=get_enum_values_as_dict(
|
||||||
|
"considerationsEnvironnementales"
|
||||||
|
),
|
||||||
|
persistence=True,
|
||||||
|
persistence_type="local",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
dcc.Download(id="download-observatoire"),
|
dcc.Download(id="download-observatoire"),
|
||||||
dbc.Button(
|
dbc.Button(
|
||||||
"Télécharger au format Excel",
|
"Télécharger au format Excel",
|
||||||
@@ -350,10 +375,13 @@ Alors, on fait comment ?
|
|||||||
Output("dashboard_titulaire_categorie", "value"),
|
Output("dashboard_titulaire_categorie", "value"),
|
||||||
Output("dashboard_titulaire_departement_code", "value"),
|
Output("dashboard_titulaire_departement_code", "value"),
|
||||||
Output("dashboard_marche_type", "value"),
|
Output("dashboard_marche_type", "value"),
|
||||||
Output("dashboard_marche_considerationsSociales", "value"),
|
|
||||||
Output("dashboard_marche_considerationsEnvironnementales", "value"),
|
|
||||||
Output("dashboard_montant_min", "value"),
|
Output("dashboard_montant_min", "value"),
|
||||||
Output("dashboard_montant_max", "value"),
|
Output("dashboard_montant_max", "value"),
|
||||||
|
Output("dashboard_marche_techniques", "value"),
|
||||||
|
Output("dashboard_marche_innovant", "value"),
|
||||||
|
Output("dashboard_marche_sousTraitanceDeclaree", "value"),
|
||||||
|
Output("dashboard_marche_considerationsSociales", "value"),
|
||||||
|
Output("dashboard_marche_considerationsEnvironnementales", "value"),
|
||||||
Input("dashboard_url", "search"),
|
Input("dashboard_url", "search"),
|
||||||
Input("dashboard_url", "pathname"),
|
Input("dashboard_url", "pathname"),
|
||||||
State("observatoire-filters", "data"),
|
State("observatoire-filters", "data"),
|
||||||
@@ -377,71 +405,11 @@ def restore_filters(search, _pathname, stored_filters):
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
return (no_update,) * 15
|
||||||
if stored_filters:
|
|
||||||
return (
|
|
||||||
stored_filters.get("year"),
|
|
||||||
stored_filters.get("acheteur_id"),
|
|
||||||
stored_filters.get("acheteur_categorie"),
|
|
||||||
stored_filters.get("acheteur_departement_code"),
|
|
||||||
stored_filters.get("titulaire_id"),
|
|
||||||
stored_filters.get("titulaire_categorie"),
|
|
||||||
stored_filters.get("titulaire_departement_code"),
|
|
||||||
stored_filters.get("marche_type"),
|
|
||||||
stored_filters.get("considerations_sociales"),
|
|
||||||
stored_filters.get("considerations_environnementales"),
|
|
||||||
stored_filters.get("montant_min"),
|
|
||||||
stored_filters.get("montant_max"),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (no_update,) * 12
|
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
|
||||||
Output("observatoire-filters", "data"),
|
|
||||||
Input("dashboard_year", "value"),
|
|
||||||
Input("dashboard_acheteur_id", "value"),
|
|
||||||
Input("dashboard_acheteur_categorie", "value"),
|
|
||||||
Input("dashboard_acheteur_departement_code", "value"),
|
|
||||||
Input("dashboard_titulaire_id", "value"),
|
|
||||||
Input("dashboard_titulaire_categorie", "value"),
|
|
||||||
Input("dashboard_titulaire_departement_code", "value"),
|
|
||||||
Input("dashboard_marche_type", "value"),
|
|
||||||
Input("dashboard_marche_considerationsSociales", "value"),
|
|
||||||
Input("dashboard_marche_considerationsEnvironnementales", "value"),
|
|
||||||
Input("dashboard_montant_min", "value"),
|
|
||||||
Input("dashboard_montant_max", "value"),
|
|
||||||
prevent_initial_call=True,
|
|
||||||
)
|
|
||||||
def save_filters_to_storage(
|
|
||||||
year,
|
|
||||||
acheteur_id,
|
|
||||||
acheteur_categorie,
|
|
||||||
acheteur_departement_code,
|
|
||||||
titulaire_id,
|
|
||||||
titulaire_categorie,
|
|
||||||
titulaire_departement_code,
|
|
||||||
marche_type,
|
|
||||||
considerations_sociales,
|
|
||||||
considerations_environnementales,
|
|
||||||
montant_min,
|
|
||||||
montant_max,
|
|
||||||
):
|
|
||||||
return {
|
|
||||||
"year": year,
|
|
||||||
"acheteur_id": acheteur_id,
|
|
||||||
"acheteur_categorie": acheteur_categorie,
|
|
||||||
"acheteur_departement_code": acheteur_departement_code,
|
|
||||||
"titulaire_id": titulaire_id,
|
|
||||||
"titulaire_categorie": titulaire_categorie,
|
|
||||||
"titulaire_departement_code": titulaire_departement_code,
|
|
||||||
"marche_type": marche_type,
|
|
||||||
"considerations_sociales": considerations_sociales,
|
|
||||||
"considerations_environnementales": considerations_environnementales,
|
|
||||||
"montant_min": montant_min,
|
|
||||||
"montant_max": montant_max,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
@@ -503,10 +471,13 @@ def sync_observatoire_share_url(acheteur_id, titulaire_id, href):
|
|||||||
Input("dashboard_titulaire_categorie", "value"),
|
Input("dashboard_titulaire_categorie", "value"),
|
||||||
Input("dashboard_titulaire_departement_code", "value"),
|
Input("dashboard_titulaire_departement_code", "value"),
|
||||||
Input("dashboard_marche_type", "value"),
|
Input("dashboard_marche_type", "value"),
|
||||||
Input("dashboard_marche_considerationsSociales", "value"),
|
|
||||||
Input("dashboard_marche_considerationsEnvironnementales", "value"),
|
|
||||||
Input("dashboard_montant_min", "value"),
|
Input("dashboard_montant_min", "value"),
|
||||||
Input("dashboard_montant_max", "value"),
|
Input("dashboard_montant_max", "value"),
|
||||||
|
Input("dashboard_marche_techniques", "value"),
|
||||||
|
Input("dashboard_marche_innovant", "value"),
|
||||||
|
Input("dashboard_marche_sousTraitanceDeclaree", "value"),
|
||||||
|
Input("dashboard_marche_considerationsSociales", "value"),
|
||||||
|
Input("dashboard_marche_considerationsEnvironnementales", "value"),
|
||||||
)
|
)
|
||||||
def udpate_dashboard_cards(
|
def udpate_dashboard_cards(
|
||||||
dashboard_year,
|
dashboard_year,
|
||||||
@@ -517,10 +488,13 @@ def udpate_dashboard_cards(
|
|||||||
dashboard_titulaire_categorie,
|
dashboard_titulaire_categorie,
|
||||||
dashboard_titulaire_departement_code,
|
dashboard_titulaire_departement_code,
|
||||||
dashboard_marche_type,
|
dashboard_marche_type,
|
||||||
dashboard_marche_considerations_sociales,
|
|
||||||
dashboard_marche_considerations_environnementales,
|
|
||||||
dashboard_montant_min,
|
dashboard_montant_min,
|
||||||
dashboard_montant_max,
|
dashboard_montant_max,
|
||||||
|
dashboard_marche_techniques,
|
||||||
|
dashboard_marche_innovant,
|
||||||
|
dashboard_marche_sous_traitance_declaree,
|
||||||
|
dashboard_marche_considerations_sociales,
|
||||||
|
dashboard_marche_considerations_environnementales,
|
||||||
):
|
):
|
||||||
lff: pl.LazyFrame = df.lazy()
|
lff: pl.LazyFrame = df.lazy()
|
||||||
lff = lff.select(
|
lff = lff.select(
|
||||||
@@ -531,23 +505,29 @@ def udpate_dashboard_cards(
|
|||||||
"montant",
|
"montant",
|
||||||
"considerationsSociales",
|
"considerationsSociales",
|
||||||
"considerationsEnvironnementales",
|
"considerationsEnvironnementales",
|
||||||
|
"marcheInnovant",
|
||||||
|
"sousTraitanceDeclaree",
|
||||||
|
"techniques",
|
||||||
"sourceDataset",
|
"sourceDataset",
|
||||||
"type",
|
"type",
|
||||||
)
|
)
|
||||||
lff = _apply_filters(
|
lff = prepare_dashboard_data(
|
||||||
lff,
|
lff=lff,
|
||||||
dashboard_year,
|
year=dashboard_year,
|
||||||
dashboard_acheteur_id,
|
acheteur_id=dashboard_acheteur_id,
|
||||||
dashboard_acheteur_categorie,
|
acheteur_categorie=dashboard_acheteur_categorie,
|
||||||
dashboard_acheteur_departement_code,
|
acheteur_departement_code=dashboard_acheteur_departement_code,
|
||||||
dashboard_titulaire_id,
|
titulaire_id=dashboard_titulaire_id,
|
||||||
dashboard_titulaire_categorie,
|
titulaire_categorie=dashboard_titulaire_categorie,
|
||||||
dashboard_titulaire_departement_code,
|
titulaire_departement_code=dashboard_titulaire_departement_code,
|
||||||
dashboard_marche_type,
|
type=dashboard_marche_type,
|
||||||
dashboard_marche_considerations_sociales,
|
considerations_sociales=dashboard_marche_considerations_sociales,
|
||||||
dashboard_marche_considerations_environnementales,
|
considerations_environnementales=dashboard_marche_considerations_environnementales,
|
||||||
montant_min=dashboard_montant_min,
|
montant_min=dashboard_montant_min,
|
||||||
montant_max=dashboard_montant_max,
|
montant_max=dashboard_montant_max,
|
||||||
|
techniques=dashboard_marche_techniques,
|
||||||
|
marche_innovant=dashboard_marche_innovant,
|
||||||
|
sous_traitance_declaree=dashboard_marche_sous_traitance_declaree,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Génération des métriques
|
# Génération des métriques
|
||||||
@@ -620,7 +600,7 @@ def udpate_dashboard_cards(
|
|||||||
cards.append(
|
cards.append(
|
||||||
make_card(
|
make_card(
|
||||||
title="Catégorie d'entreprise",
|
title="Catégorie d'entreprise",
|
||||||
subtitle="en nombre de marchés attribués",
|
subtitle="en nombre de titulaires",
|
||||||
fig=donut_titulaire_categorie,
|
fig=donut_titulaire_categorie,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -683,41 +663,50 @@ def udpate_dashboard_cards(
|
|||||||
State("dashboard_titulaire_categorie", "value"),
|
State("dashboard_titulaire_categorie", "value"),
|
||||||
State("dashboard_titulaire_departement_code", "value"),
|
State("dashboard_titulaire_departement_code", "value"),
|
||||||
State("dashboard_marche_type", "value"),
|
State("dashboard_marche_type", "value"),
|
||||||
State("dashboard_marche_considerationsSociales", "value"),
|
|
||||||
State("dashboard_marche_considerationsEnvironnementales", "value"),
|
|
||||||
State("dashboard_montant_min", "value"),
|
State("dashboard_montant_min", "value"),
|
||||||
State("dashboard_montant_max", "value"),
|
State("dashboard_montant_max", "value"),
|
||||||
|
State("dashboard_marche_techniques", "value"),
|
||||||
|
State("dashboard_marche_innovant", "value"),
|
||||||
|
State("dashboard_marche_sousTraitanceDeclaree", "value"),
|
||||||
|
State("dashboard_marche_considerationsSociales", "value"),
|
||||||
|
State("dashboard_marche_considerationsEnvironnementales", "value"),
|
||||||
prevent_initial_call=True,
|
prevent_initial_call=True,
|
||||||
)
|
)
|
||||||
def download_observatoire(
|
def download_observatoire(
|
||||||
_n_clicks,
|
_n_clicks,
|
||||||
year,
|
dashboard_year,
|
||||||
acheteur_id,
|
dashboard_acheteur_id,
|
||||||
acheteur_categorie,
|
dashboard_acheteur_categorie,
|
||||||
acheteur_departement_code,
|
dashboard_acheteur_departement_code,
|
||||||
titulaire_id,
|
dashboard_titulaire_id,
|
||||||
titulaire_categorie,
|
dashboard_titulaire_categorie,
|
||||||
titulaire_departement_code,
|
dashboard_titulaire_departement_code,
|
||||||
marche_type,
|
dashboard_marche_type,
|
||||||
considerations_sociales,
|
dashboard_montant_min,
|
||||||
considerations_environnementales,
|
dashboard_montant_max,
|
||||||
montant_min,
|
dashboard_marche_techniques,
|
||||||
montant_max,
|
dashboard_marche_innovant,
|
||||||
|
dashboard_marche_sous_traitance_declaree,
|
||||||
|
dashboard_considerations_sociales,
|
||||||
|
dashboard_considerations_environnementales,
|
||||||
):
|
):
|
||||||
lff = _apply_filters(
|
lff = prepare_dashboard_data(
|
||||||
df.lazy(),
|
lff=df.lazy(),
|
||||||
year,
|
year=dashboard_year,
|
||||||
acheteur_id,
|
acheteur_id=dashboard_acheteur_id,
|
||||||
acheteur_categorie,
|
acheteur_categorie=dashboard_acheteur_categorie,
|
||||||
acheteur_departement_code,
|
acheteur_departement_code=dashboard_acheteur_departement_code,
|
||||||
titulaire_id,
|
titulaire_id=dashboard_titulaire_id,
|
||||||
titulaire_categorie,
|
titulaire_categorie=dashboard_titulaire_categorie,
|
||||||
titulaire_departement_code,
|
titulaire_departement_code=dashboard_titulaire_departement_code,
|
||||||
marche_type,
|
type=dashboard_marche_type,
|
||||||
considerations_sociales,
|
considerations_sociales=dashboard_considerations_sociales,
|
||||||
considerations_environnementales,
|
considerations_environnementales=dashboard_considerations_environnementales,
|
||||||
montant_min=montant_min,
|
montant_min=dashboard_montant_min,
|
||||||
montant_max=montant_max,
|
montant_max=dashboard_montant_max,
|
||||||
|
techniques=dashboard_marche_techniques,
|
||||||
|
marche_innovant=dashboard_marche_innovant,
|
||||||
|
sous_traitance_declaree=dashboard_marche_sous_traitance_declaree,
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_bytes(buffer):
|
def to_bytes(buffer):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from time import localtime, sleep
|
from time import localtime, sleep
|
||||||
|
|
||||||
import polars as pl
|
import polars as pl
|
||||||
@@ -694,6 +695,96 @@ def prepare_table_data(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_dashboard_data(
|
||||||
|
lff: pl.LazyFrame,
|
||||||
|
year,
|
||||||
|
acheteur_id,
|
||||||
|
acheteur_categorie,
|
||||||
|
acheteur_departement_code,
|
||||||
|
titulaire_id,
|
||||||
|
titulaire_categorie,
|
||||||
|
titulaire_departement_code,
|
||||||
|
type,
|
||||||
|
considerations_sociales,
|
||||||
|
considerations_environnementales,
|
||||||
|
techniques,
|
||||||
|
marche_innovant,
|
||||||
|
sous_traitance_declaree,
|
||||||
|
montant_min=None,
|
||||||
|
montant_max=None,
|
||||||
|
) -> pl.LazyFrame:
|
||||||
|
if year:
|
||||||
|
lff = lff.filter(pl.col("dateNotification").dt.year() == int(year))
|
||||||
|
else:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
||||||
|
)
|
||||||
|
|
||||||
|
if acheteur_id:
|
||||||
|
lff = lff.filter(pl.col("acheteur_id").str.contains(acheteur_id))
|
||||||
|
else:
|
||||||
|
if acheteur_categorie:
|
||||||
|
lff = lff.filter(pl.col("acheteur_categorie") == acheteur_categorie)
|
||||||
|
if acheteur_departement_code:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("acheteur_departement_code").is_in(acheteur_departement_code)
|
||||||
|
)
|
||||||
|
|
||||||
|
if titulaire_id:
|
||||||
|
lff = lff.filter(pl.col("titulaire_id").str.contains(titulaire_id))
|
||||||
|
else:
|
||||||
|
if titulaire_categorie:
|
||||||
|
lff = lff.filter(pl.col("titulaire_categorie") == titulaire_categorie)
|
||||||
|
if titulaire_departement_code:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("titulaire_departement_code").is_in(titulaire_departement_code)
|
||||||
|
)
|
||||||
|
|
||||||
|
if type:
|
||||||
|
lff = lff.filter(pl.col("type") == type)
|
||||||
|
|
||||||
|
if marche_innovant != "all":
|
||||||
|
lff = lff.filter(pl.col("marcheInnovant") == marche_innovant)
|
||||||
|
|
||||||
|
if sous_traitance_declaree != "all":
|
||||||
|
lff = lff.filter(pl.col("sousTraitanceDeclaree") == sous_traitance_declaree)
|
||||||
|
|
||||||
|
if techniques:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("techniques")
|
||||||
|
.str.split(", ")
|
||||||
|
.list.set_intersection(techniques)
|
||||||
|
.list.len()
|
||||||
|
> 0
|
||||||
|
)
|
||||||
|
|
||||||
|
if considerations_sociales:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("considerationsSociales")
|
||||||
|
.str.split(", ")
|
||||||
|
.list.set_intersection(considerations_sociales)
|
||||||
|
.list.len()
|
||||||
|
> 0
|
||||||
|
)
|
||||||
|
|
||||||
|
if considerations_environnementales:
|
||||||
|
lff = lff.filter(
|
||||||
|
pl.col("considerationsEnvironnementales")
|
||||||
|
.str.split(", ")
|
||||||
|
.list.set_intersection(considerations_environnementales)
|
||||||
|
.list.len()
|
||||||
|
> 0
|
||||||
|
)
|
||||||
|
|
||||||
|
if montant_min is not None:
|
||||||
|
lff = lff.filter(pl.col("montant") >= montant_min)
|
||||||
|
|
||||||
|
if montant_max is not None:
|
||||||
|
lff = lff.filter(pl.col("montant") <= montant_max)
|
||||||
|
|
||||||
|
return lff
|
||||||
|
|
||||||
|
|
||||||
def get_button_properties(height):
|
def get_button_properties(height):
|
||||||
if height > 65000:
|
if height > 65000:
|
||||||
download_disabled = True
|
download_disabled = True
|
||||||
|
|||||||
Reference in New Issue
Block a user