Merge tag 'v2.7.1' into dev
- Correction du partage de données filtrées entre dashboard et vue des données
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
#### 2.7.1 (23 mars 2026)
|
||||||
|
|
||||||
|
- Correction du partage de données filtrées entre dashboard et vue des données
|
||||||
|
|
||||||
#### 2.7.0 (23 mars 2026)
|
#### 2.7.0 (23 mars 2026)
|
||||||
|
|
||||||
- Remplacement de la page Statistiques par l'observatoire
|
- Remplacement de la page Statistiques par l'observatoire
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# decp.info
|
# decp.info
|
||||||
|
|
||||||
> v2.7.0
|
> v2.7.1
|
||||||
> Outil d'exploration et de téléchargement des données essentielles de la commande publique.
|
> Outil d'exploration et de téléchargement des données essentielles de la commande publique.
|
||||||
|
|
||||||
=> [decp.info](https://decp.info)
|
=> [decp.info](https://decp.info)
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "decp.info"
|
name = "decp.info"
|
||||||
description = "Interface d'exploration et d'analyse des marchés publics français."
|
description = "Interface d'exploration et d'analyse des marchés publics français."
|
||||||
version = "2.7.0"
|
version = "2.7.1"
|
||||||
requires-python = ">= 3.10"
|
requires-python = ">= 3.10"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Colin Maudry", email = "colin@colmo.tech" }
|
{ name = "Colin Maudry", email = "colin@colmo.tech" }
|
||||||
|
|||||||
+32
-146
@@ -90,8 +90,6 @@ OBSERVATOIRE_COLUMNS = [
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
DF_FILTERED: pl.DataFrame = pl.DataFrame()
|
|
||||||
|
|
||||||
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"),
|
||||||
@@ -324,7 +322,7 @@ Alors, on fait comment ?
|
|||||||
dbc.Col("Sous-traitance :", lg=5),
|
dbc.Col("Sous-traitance :", lg=5),
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
dbc.RadioItems(
|
dbc.RadioItems(
|
||||||
id="dashboard_marche_sousTraitanceDeclaree",
|
id="dashboard_marche_sous_traitance_declaree",
|
||||||
options=[
|
options=[
|
||||||
{
|
{
|
||||||
"label": "Tous",
|
"label": "Tous",
|
||||||
@@ -380,7 +378,7 @@ Alors, on fait comment ?
|
|||||||
dbc.Row(
|
dbc.Row(
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
id="dashboard_marche_considerationsSociales",
|
id="dashboard_marche_considerations_sociales",
|
||||||
placeholder="Considérations sociales",
|
placeholder="Considérations sociales",
|
||||||
options=get_enum_values_as_dict(
|
options=get_enum_values_as_dict(
|
||||||
"considerationsSociales"
|
"considerationsSociales"
|
||||||
@@ -394,7 +392,7 @@ Alors, on fait comment ?
|
|||||||
dbc.Row(
|
dbc.Row(
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
id="dashboard_marche_considerationsEnvironnementales",
|
id="dashboard_marche_considerations_environnementales",
|
||||||
placeholder="Considérations environnementales",
|
placeholder="Considérations environnementales",
|
||||||
multi=True,
|
multi=True,
|
||||||
options=get_enum_values_as_dict(
|
options=get_enum_values_as_dict(
|
||||||
@@ -544,30 +542,14 @@ FILTER_PARAMS = [
|
|||||||
("dashboard_montant_max", "montant_max", False, None),
|
("dashboard_montant_max", "montant_max", False, None),
|
||||||
("dashboard_marche_techniques", "techniques", True, None),
|
("dashboard_marche_techniques", "techniques", True, None),
|
||||||
("dashboard_marche_innovant", "innovant", False, "all"),
|
("dashboard_marche_innovant", "innovant", False, "all"),
|
||||||
("dashboard_marche_sousTraitanceDeclaree", "sous_traitance", False, "all"),
|
("dashboard_marche_sous_traitance_declaree", "sous_traitance", False, "all"),
|
||||||
("dashboard_marche_considerationsSociales", "social", True, None),
|
("dashboard_marche_considerations_sociales", "social", True, None),
|
||||||
("dashboard_marche_considerationsEnvironnementales", "env", True, None),
|
("dashboard_marche_considerations_environnementales", "env", True, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("dashboard_year", "value"),
|
*[Output(fp[0], "value") for fp in FILTER_PARAMS],
|
||||||
Output("dashboard_acheteur_id", "value"),
|
|
||||||
Output("dashboard_acheteur_categorie", "value"),
|
|
||||||
Output("dashboard_acheteur_departement_code", "value"),
|
|
||||||
Output("dashboard_titulaire_id", "value"),
|
|
||||||
Output("dashboard_titulaire_categorie", "value"),
|
|
||||||
Output("dashboard_titulaire_departement_code", "value"),
|
|
||||||
Output("dashboard_marche_type", "value"),
|
|
||||||
Output("dashboard_marche_objet", "value"),
|
|
||||||
Output("dashboard_marche_code_cpv", "value"),
|
|
||||||
Output("dashboard_montant_min", "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"),
|
||||||
@@ -670,73 +652,26 @@ def show_confirmation(n_clicks):
|
|||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("cards", "children"),
|
Output("cards", "children"),
|
||||||
Input("dashboard_year", "value"),
|
Output("observatoire-filters", "data"),
|
||||||
Input("dashboard_acheteur_id", "value"),
|
*[Input(fp[0], "value") for fp in FILTER_PARAMS],
|
||||||
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_objet", "value"),
|
|
||||||
Input("dashboard_marche_code_cpv", "value"),
|
|
||||||
Input("dashboard_montant_min", "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(*filter_values):
|
||||||
dashboard_year,
|
|
||||||
dashboard_acheteur_id,
|
|
||||||
dashboard_acheteur_categorie,
|
|
||||||
dashboard_acheteur_departement_code,
|
|
||||||
dashboard_titulaire_id,
|
|
||||||
dashboard_titulaire_categorie,
|
|
||||||
dashboard_titulaire_departement_code,
|
|
||||||
dashboard_marche_type,
|
|
||||||
dashboard_marche_objet,
|
|
||||||
dashboard_marche_code_cpv,
|
|
||||||
dashboard_montant_min,
|
|
||||||
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()
|
||||||
|
|
||||||
# Filtrage des données
|
# Filtrage des données
|
||||||
lff = prepare_dashboard_data(
|
filter_params = {}
|
||||||
lff=lff,
|
for (input_id, url_key, is_multi, default), value in zip(
|
||||||
year=dashboard_year,
|
FILTER_PARAMS, filter_values
|
||||||
acheteur_id=dashboard_acheteur_id,
|
):
|
||||||
acheteur_categorie=dashboard_acheteur_categorie,
|
filter_params[input_id] = value
|
||||||
acheteur_departement_code=dashboard_acheteur_departement_code,
|
|
||||||
titulaire_id=dashboard_titulaire_id,
|
print(filter_params)
|
||||||
titulaire_categorie=dashboard_titulaire_categorie,
|
|
||||||
titulaire_departement_code=dashboard_titulaire_departement_code,
|
lff = prepare_dashboard_data(lff=lff, **filter_params)
|
||||||
type=dashboard_marche_type,
|
|
||||||
objet=dashboard_marche_objet,
|
|
||||||
code_cpv=dashboard_marche_code_cpv,
|
|
||||||
considerations_sociales=dashboard_marche_considerations_sociales,
|
|
||||||
considerations_environnementales=dashboard_marche_considerations_environnementales,
|
|
||||||
montant_min=dashboard_montant_min,
|
|
||||||
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
|
||||||
dff = lff.collect(engine="streaming")
|
dff = lff.collect(engine="streaming")
|
||||||
|
|
||||||
global DF_FILTERED
|
|
||||||
DF_FILTERED = dff
|
|
||||||
|
|
||||||
logger.debug("Filter data: " + str(dff.height))
|
logger.debug("Filter data: " + str(dff.height))
|
||||||
|
|
||||||
df_per_uid = (
|
df_per_uid = (
|
||||||
@@ -832,73 +767,18 @@ def udpate_dashboard_cards(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return dbc.Row(children=cards + geographic_maps + other_cards)
|
return dbc.Row(children=cards + geographic_maps + other_cards), filter_params
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("download-observatoire", "data"),
|
Output("download-observatoire", "data"),
|
||||||
Input("btn-download-observatoire", "n_clicks"),
|
Input("btn-download-observatoire", "n_clicks"),
|
||||||
State("dashboard_year", "value"),
|
State("observatoire-filters", "data"),
|
||||||
State("dashboard_acheteur_id", "value"),
|
|
||||||
State("dashboard_acheteur_categorie", "value"),
|
|
||||||
State("dashboard_acheteur_departement_code", "value"),
|
|
||||||
State("dashboard_titulaire_id", "value"),
|
|
||||||
State("dashboard_titulaire_categorie", "value"),
|
|
||||||
State("dashboard_titulaire_departement_code", "value"),
|
|
||||||
State("dashboard_marche_type", "value"),
|
|
||||||
State("dashboard_marche_objet", "value"),
|
|
||||||
State("dashboard_marche_code_cpv", "value"),
|
|
||||||
State("dashboard_montant_min", "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"),
|
|
||||||
State("observatoire-hidden-columns", "data"),
|
State("observatoire-hidden-columns", "data"),
|
||||||
prevent_initial_call=True,
|
prevent_initial_call=True,
|
||||||
)
|
)
|
||||||
def download_observatoire(
|
def download_observatoire(_n_clicks, filter_params, hidden_columns):
|
||||||
_n_clicks,
|
lff = prepare_dashboard_data(lff=df.lazy(), **(filter_params or {}))
|
||||||
dashboard_year,
|
|
||||||
dashboard_acheteur_id,
|
|
||||||
dashboard_acheteur_categorie,
|
|
||||||
dashboard_acheteur_departement_code,
|
|
||||||
dashboard_titulaire_id,
|
|
||||||
dashboard_titulaire_categorie,
|
|
||||||
dashboard_titulaire_departement_code,
|
|
||||||
dashboard_marche_type,
|
|
||||||
dashboard_marche_objet,
|
|
||||||
dashboard_marche_code_cpv,
|
|
||||||
dashboard_montant_min,
|
|
||||||
dashboard_montant_max,
|
|
||||||
dashboard_marche_techniques,
|
|
||||||
dashboard_marche_innovant,
|
|
||||||
dashboard_marche_sous_traitance_declaree,
|
|
||||||
dashboard_considerations_sociales,
|
|
||||||
dashboard_considerations_environnementales,
|
|
||||||
hidden_columns,
|
|
||||||
):
|
|
||||||
lff = prepare_dashboard_data(
|
|
||||||
lff=df.lazy(),
|
|
||||||
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,
|
|
||||||
type=dashboard_marche_type,
|
|
||||||
objet=dashboard_marche_objet,
|
|
||||||
code_cpv=dashboard_marche_code_cpv,
|
|
||||||
considerations_sociales=dashboard_considerations_sociales,
|
|
||||||
considerations_environnementales=dashboard_considerations_environnementales,
|
|
||||||
montant_min=dashboard_montant_min,
|
|
||||||
montant_max=dashboard_montant_max,
|
|
||||||
techniques=dashboard_marche_techniques,
|
|
||||||
marche_innovant=dashboard_marche_innovant,
|
|
||||||
sous_traitance_declaree=dashboard_marche_sous_traitance_declaree,
|
|
||||||
)
|
|
||||||
|
|
||||||
if hidden_columns:
|
if hidden_columns:
|
||||||
lff = lff.drop(hidden_columns)
|
lff = lff.drop(hidden_columns)
|
||||||
@@ -974,16 +854,22 @@ def toggle_observatoire_preview(n_clicks, is_open):
|
|||||||
Input("observatoire-preview-table", "page_size"),
|
Input("observatoire-preview-table", "page_size"),
|
||||||
Input("observatoire-preview-table", "sort_by"),
|
Input("observatoire-preview-table", "sort_by"),
|
||||||
State("observatoire-preview-table", "data_timestamp"),
|
State("observatoire-preview-table", "data_timestamp"),
|
||||||
|
State("observatoire-filters", "data"),
|
||||||
prevent_initial_call=True,
|
prevent_initial_call=True,
|
||||||
)
|
)
|
||||||
def populate_preview_table(
|
def populate_preview_table(
|
||||||
is_open, filter_query, page_current, page_size, sort_by, data_timestamp
|
is_open,
|
||||||
|
filter_query,
|
||||||
|
page_current,
|
||||||
|
page_size,
|
||||||
|
sort_by,
|
||||||
|
data_timestamp,
|
||||||
|
filter_params,
|
||||||
):
|
):
|
||||||
if not is_open:
|
if not is_open:
|
||||||
return (no_update,) * 9
|
return (no_update,) * 9
|
||||||
|
|
||||||
global DF_FILTERED
|
lff = prepare_dashboard_data(lff=df.lazy(), **(filter_params or {}))
|
||||||
lff = DF_FILTERED.lazy()
|
|
||||||
|
|
||||||
return prepare_table_data(
|
return prepare_table_data(
|
||||||
lff,
|
lff,
|
||||||
|
|||||||
+51
-51
@@ -699,98 +699,98 @@ def prepare_table_data(
|
|||||||
|
|
||||||
def prepare_dashboard_data(
|
def prepare_dashboard_data(
|
||||||
lff: pl.LazyFrame,
|
lff: pl.LazyFrame,
|
||||||
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,
|
||||||
type,
|
dashboard_marche_type,
|
||||||
objet,
|
dashboard_marche_objet,
|
||||||
code_cpv,
|
dashboard_marche_code_cpv,
|
||||||
considerations_sociales,
|
dashboard_marche_considerations_sociales,
|
||||||
considerations_environnementales,
|
dashboard_marche_considerations_environnementales,
|
||||||
techniques,
|
dashboard_marche_techniques,
|
||||||
marche_innovant,
|
dashboard_marche_innovant,
|
||||||
sous_traitance_declaree,
|
dashboard_marche_sous_traitance_declaree,
|
||||||
montant_min=None,
|
dashboard_montant_min=None,
|
||||||
montant_max=None,
|
dashboard_montant_max=None,
|
||||||
) -> pl.LazyFrame:
|
) -> pl.LazyFrame:
|
||||||
if year:
|
if dashboard_year:
|
||||||
lff = lff.filter(pl.col("dateNotification").dt.year() == int(year))
|
lff = lff.filter(pl.col("dateNotification").dt.year() == int(dashboard_year))
|
||||||
else:
|
else:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
||||||
)
|
)
|
||||||
|
|
||||||
if acheteur_id:
|
if dashboard_acheteur_id:
|
||||||
lff = lff.filter(pl.col("acheteur_id").str.contains(acheteur_id))
|
lff = lff.filter(pl.col("acheteur_id").str.contains(dashboard_acheteur_id))
|
||||||
else:
|
else:
|
||||||
if acheteur_categorie:
|
if dashboard_acheteur_categorie:
|
||||||
lff = lff.filter(pl.col("acheteur_categorie") == acheteur_categorie)
|
lff = lff.filter(pl.col("acheteur_categorie") == dashboard_acheteur_categorie)
|
||||||
if acheteur_departement_code:
|
if dashboard_acheteur_departement_code:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("acheteur_departement_code").is_in(acheteur_departement_code)
|
pl.col("acheteur_departement_code").is_in(dashboard_acheteur_departement_code)
|
||||||
)
|
)
|
||||||
|
|
||||||
if titulaire_id:
|
if dashboard_titulaire_id:
|
||||||
lff = lff.filter(pl.col("titulaire_id").str.contains(titulaire_id))
|
lff = lff.filter(pl.col("titulaire_id").str.contains(dashboard_titulaire_id))
|
||||||
else:
|
else:
|
||||||
if titulaire_categorie:
|
if dashboard_titulaire_categorie:
|
||||||
lff = lff.filter(pl.col("titulaire_categorie") == titulaire_categorie)
|
lff = lff.filter(pl.col("titulaire_categorie") == dashboard_titulaire_categorie)
|
||||||
if titulaire_departement_code:
|
if dashboard_titulaire_departement_code:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("titulaire_departement_code").is_in(titulaire_departement_code)
|
pl.col("titulaire_departement_code").is_in(dashboard_titulaire_departement_code)
|
||||||
)
|
)
|
||||||
|
|
||||||
if type:
|
if dashboard_marche_type:
|
||||||
lff = lff.filter(pl.col("type") == type)
|
lff = lff.filter(pl.col("type") == dashboard_marche_type)
|
||||||
|
|
||||||
if objet:
|
if dashboard_marche_objet:
|
||||||
lff = lff.filter(pl.col("objet").str.contains(f"(?i){objet}"))
|
lff = lff.filter(pl.col("objet").str.contains(f"(?i){dashboard_marche_objet}"))
|
||||||
|
|
||||||
if code_cpv:
|
if dashboard_marche_code_cpv:
|
||||||
lff = lff.filter(pl.col("codeCPV").str.starts_with(code_cpv))
|
lff = lff.filter(pl.col("codeCPV").str.starts_with(dashboard_marche_code_cpv))
|
||||||
|
|
||||||
if marche_innovant and marche_innovant != "all":
|
if dashboard_marche_innovant and dashboard_marche_innovant != "all":
|
||||||
lff = lff.filter(pl.col("marcheInnovant") == marche_innovant)
|
lff = lff.filter(pl.col("marcheInnovant") == dashboard_marche_innovant)
|
||||||
|
|
||||||
if sous_traitance_declaree and sous_traitance_declaree != "all":
|
if dashboard_marche_sous_traitance_declaree and dashboard_marche_sous_traitance_declaree != "all":
|
||||||
lff = lff.filter(pl.col("sousTraitanceDeclaree") == sous_traitance_declaree)
|
lff = lff.filter(pl.col("sousTraitanceDeclaree") == dashboard_marche_sous_traitance_declaree)
|
||||||
|
|
||||||
if techniques:
|
if dashboard_marche_techniques:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("techniques")
|
pl.col("techniques")
|
||||||
.str.split(", ")
|
.str.split(", ")
|
||||||
.list.set_intersection(techniques)
|
.list.set_intersection(dashboard_marche_techniques)
|
||||||
.list.len()
|
.list.len()
|
||||||
> 0
|
> 0
|
||||||
)
|
)
|
||||||
|
|
||||||
if considerations_sociales:
|
if dashboard_marche_considerations_sociales:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("considerationsSociales")
|
pl.col("considerationsSociales")
|
||||||
.str.split(", ")
|
.str.split(", ")
|
||||||
.list.set_intersection(considerations_sociales)
|
.list.set_intersection(dashboard_marche_considerations_sociales)
|
||||||
.list.len()
|
.list.len()
|
||||||
> 0
|
> 0
|
||||||
)
|
)
|
||||||
|
|
||||||
if considerations_environnementales:
|
if dashboard_marche_considerations_environnementales:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
pl.col("considerationsEnvironnementales")
|
pl.col("considerationsEnvironnementales")
|
||||||
.str.split(", ")
|
.str.split(", ")
|
||||||
.list.set_intersection(considerations_environnementales)
|
.list.set_intersection(dashboard_marche_considerations_environnementales)
|
||||||
.list.len()
|
.list.len()
|
||||||
> 0
|
> 0
|
||||||
)
|
)
|
||||||
|
|
||||||
if montant_min is not None:
|
if dashboard_montant_min is not None:
|
||||||
lff = lff.filter(pl.col("montant") >= montant_min)
|
lff = lff.filter(pl.col("montant") >= dashboard_montant_min)
|
||||||
|
|
||||||
if montant_max is not None:
|
if dashboard_montant_max is not None:
|
||||||
lff = lff.filter(pl.col("montant") <= montant_max)
|
lff = lff.filter(pl.col("montant") <= dashboard_montant_max)
|
||||||
|
|
||||||
return lff
|
return lff
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -234,23 +234,23 @@ def test_010_observatoire_montant_filter():
|
|||||||
def apply(min_val=None, max_val=None):
|
def apply(min_val=None, max_val=None):
|
||||||
return prepare_dashboard_data(
|
return prepare_dashboard_data(
|
||||||
data.lazy(),
|
data.lazy(),
|
||||||
year="2025",
|
dashboard_year="2025",
|
||||||
acheteur_id=None,
|
dashboard_acheteur_id=None,
|
||||||
acheteur_categorie=None,
|
dashboard_acheteur_categorie=None,
|
||||||
acheteur_departement_code=None,
|
dashboard_acheteur_departement_code=None,
|
||||||
titulaire_id=None,
|
dashboard_titulaire_id=None,
|
||||||
titulaire_categorie=None,
|
dashboard_titulaire_categorie=None,
|
||||||
titulaire_departement_code=None,
|
dashboard_titulaire_departement_code=None,
|
||||||
type=None,
|
dashboard_marche_type=None,
|
||||||
objet=None,
|
dashboard_marche_objet=None,
|
||||||
code_cpv=None,
|
dashboard_marche_code_cpv=None,
|
||||||
considerations_sociales=None,
|
dashboard_marche_considerations_sociales=None,
|
||||||
considerations_environnementales=None,
|
dashboard_marche_considerations_environnementales=None,
|
||||||
techniques=None,
|
dashboard_marche_techniques=None,
|
||||||
marche_innovant=None,
|
dashboard_marche_innovant=None,
|
||||||
sous_traitance_declaree=None,
|
dashboard_marche_sous_traitance_declaree=None,
|
||||||
montant_min=min_val,
|
dashboard_montant_min=min_val,
|
||||||
montant_max=max_val,
|
dashboard_montant_max=max_val,
|
||||||
).collect()
|
).collect()
|
||||||
|
|
||||||
assert apply().height == 3
|
assert apply().height == 3
|
||||||
|
|||||||
Reference in New Issue
Block a user