territories-dashboard-lib 0.1.39b2__py3-none-any.whl → 1.1.1.dev10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of territories-dashboard-lib might be problematic. Click here for more details.

Files changed (66) hide show
  1. territories_dashboard_lib/geo_lib/admin.py +2 -0
  2. territories_dashboard_lib/geo_lib/migrations/0003_geofeature_color_column_geofeature_size_column.py +23 -0
  3. territories_dashboard_lib/geo_lib/models.py +12 -0
  4. territories_dashboard_lib/geo_lib/payloads.py +7 -21
  5. territories_dashboard_lib/geo_lib/views.py +58 -53
  6. territories_dashboard_lib/indicators_lib/enums.py +61 -37
  7. territories_dashboard_lib/indicators_lib/migrations/0004_alter_indicator_min_mesh.py +18 -0
  8. territories_dashboard_lib/indicators_lib/migrations/0005_auto_20251203_1621.py +2 -2
  9. territories_dashboard_lib/indicators_lib/models.py +9 -6
  10. territories_dashboard_lib/indicators_lib/payloads.py +14 -1
  11. territories_dashboard_lib/indicators_lib/query/commons.py +90 -104
  12. territories_dashboard_lib/indicators_lib/query/comparison.py +8 -3
  13. territories_dashboard_lib/indicators_lib/query/details.py +8 -13
  14. territories_dashboard_lib/indicators_lib/query/histogram.py +0 -1
  15. territories_dashboard_lib/indicators_lib/query/indicator_card.py +12 -7
  16. territories_dashboard_lib/indicators_lib/query/top_10.py +12 -12
  17. territories_dashboard_lib/indicators_lib/query/utils.py +9 -0
  18. territories_dashboard_lib/indicators_lib/table.py +15 -12
  19. territories_dashboard_lib/indicators_lib/views.py +49 -59
  20. territories_dashboard_lib/superset_lib/logic.py +24 -25
  21. territories_dashboard_lib/superset_lib/migrations/0002_alter_filter_mesh.py +18 -0
  22. territories_dashboard_lib/tracking_lib/enums.py +2 -0
  23. territories_dashboard_lib/tracking_lib/migrations/0005_alter_page_cmp_territory_mesh_alter_page_submesh_and_more.py +28 -0
  24. territories_dashboard_lib/tracking_lib/migrations/0006_alter_event_name.py +18 -0
  25. territories_dashboard_lib/tracking_lib/payloads.py +4 -2
  26. territories_dashboard_lib/tracking_lib/views.py +7 -6
  27. territories_dashboard_lib/website_lib/conf.py +14 -0
  28. territories_dashboard_lib/website_lib/context_processors.py +2 -1
  29. territories_dashboard_lib/website_lib/migrations/0005_mainconf_meshes.py +20 -0
  30. territories_dashboard_lib/website_lib/models.py +12 -0
  31. territories_dashboard_lib/website_lib/params.py +34 -22
  32. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/anchor.mjs +43 -0
  33. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/page.mjs +7 -9
  34. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/page.mjs +2 -7
  35. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/dom.mjs +0 -15
  36. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/enums.mjs +13 -10
  37. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/side_panel.mjs +1 -15
  38. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/page.mjs +7 -9
  39. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/track-visible-indicators.mjs +121 -0
  40. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +2 -0
  41. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +2 -0
  42. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors.bundle.js +2 -0
  43. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.css +12 -0
  44. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/page.html +4 -3
  45. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/anchor.html +14 -0
  46. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/geo_params.html +3 -3
  47. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/indicator-card.html +14 -8
  48. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/select_territory.html +32 -0
  49. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.html +8 -35
  50. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/histogram.html +1 -1
  51. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.html +9 -8
  52. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/methodo/methodo.js +28 -0
  53. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/methodo/page.html +40 -0
  54. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +4 -5
  55. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/sitemap/page.html +9 -0
  56. territories_dashboard_lib/website_lib/templatetags/other_filters.py +6 -3
  57. territories_dashboard_lib/website_lib/views.py +100 -0
  58. {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/METADATA +2 -2
  59. {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/RECORD +62 -51
  60. territories_dashboard_lib/indicators_lib/migrations/0006_alter_theme_action_theme_alter_theme_objectif_theme.py +0 -23
  61. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.css +0 -29
  62. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +0 -45
  63. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.js +0 -19
  64. {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/WHEEL +0 -0
  65. {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/licenses/licence.md +0 -0
  66. {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,55 @@
1
- from ..enums import (
2
- FRANCE_DB_VALUES,
3
- MeshLevel,
4
- )
1
+ from territories_dashboard_lib.indicators_lib.payloads import Territory
2
+
3
+ from ..enums import FRANCE_DB_VALUES, MeshLevel
5
4
  from ..models import AggregationFunctions, Indicator
6
- from .utils import get_breakdown_dimension, run_custom_query
5
+ from .utils import format_sql_codes, get_breakdown_dimension, run_custom_query
6
+
7
+
8
+ def get_mesh_column_name(mesh: MeshLevel):
9
+ return f"code_{mesh}"
10
+
11
+
12
+ def get_sub_territories(
13
+ *,
14
+ submesh: MeshLevel,
15
+ territory: Territory = None,
16
+ with_center=False,
17
+ codes: list[str] = None,
18
+ ):
19
+ """
20
+ Récupère une liste des territoires appartenant à un territoire parent.
21
+ params:
22
+ submesh: maille des sous-territoires à récupérer
23
+ territory: territoire parent des sous-territoires
24
+ with_center: si True, ajoute le centre de chaque territoire
25
+ codes: codes des sous-territoires à récupérer, peut-être utilisé en absence du territoire parent
26
+ """
27
+ parent_mesh_join = ""
28
+ condition = ""
29
+ if territory is None and codes:
30
+ condition = f"WHERE arbo.code IN {format_sql_codes(codes)}"
31
+ elif territory and submesh == territory.mesh:
32
+ condition = f"WHERE arbo.code IN {territory.sql_codes}"
33
+ elif territory:
34
+ parent_mesh_join = f"JOIN arbo_{territory.mesh}_{submesh} AS j ON j.{submesh}=arbo.code AND j.{territory.mesh} IN {territory.sql_codes}"
35
+
36
+ center = ""
37
+ contours_join = ""
38
+ if with_center:
39
+ center = ", ST_ASGEOJSON(ST_CENTROID(contours.geometry)) as center"
40
+ contours_join = f"JOIN contours_simplified_{submesh} as contours ON arbo.code = contours.code"
41
+
42
+ query = f"""
43
+ SELECT DISTINCT
44
+ arbo.code,
45
+ arbo.name
46
+ {center}
47
+ FROM arbo_{submesh} AS arbo
48
+ {parent_mesh_join}
49
+ {contours_join}
50
+ {condition}
51
+ """
52
+ return run_custom_query(query)
7
53
 
8
54
 
9
55
  def get_last_year(indicator, mesh):
@@ -18,9 +64,9 @@ def generate_aggregate_query(indicator, territory, submesh, filters, slicer):
18
64
  aggregat AS
19
65
  (
20
66
  SELECT
21
- {calculate_aggregate_values(indicator)}, {slicer}
67
+ {calculate_aggregate_values(indicator)}, indic.{slicer}
22
68
  FROM
23
- {get_table_data_for_geography(indicator, territory, submesh)}
69
+ {get_values_for_indicator_territory_submesh(indicator=indicator, territory=territory, submesh=submesh)}
24
70
  {add_optional_filters(indicator, filters)}
25
71
  AND annee = (SELECT * FROM annee_max)
26
72
  GROUP BY (indic.{slicer})
@@ -30,9 +76,8 @@ def generate_aggregate_query(indicator, territory, submesh, filters, slicer):
30
76
 
31
77
 
32
78
  def generate_aggregate_query_for_location(indicator, territory, submesh, filters):
33
- return generate_aggregate_query(
34
- indicator, territory, submesh, filters, f"code_{submesh}"
35
- )
79
+ mesh_col = get_mesh_column_name(submesh)
80
+ return generate_aggregate_query(indicator, territory, submesh, filters, mesh_col)
36
81
 
37
82
 
38
83
  def add_optional_filters(indicator: Indicator, filters):
@@ -47,75 +92,48 @@ def add_optional_filters(indicator: Indicator, filters):
47
92
  return condition
48
93
 
49
94
 
50
- def get_place_names_join(include_place_name, mapped_submesh, submesh, flows=False):
51
- join_clause = ""
52
- if include_place_name:
53
- if flows:
54
- join_clause = f"""
55
- JOIN
56
- (SELECT distinct("NOM_{mapped_submesh}") as territory_1, "{mapped_submesh}" as territory_1_id, "{mapped_submesh}" from arborescence_geo) arbo1
57
- on arbo1."{mapped_submesh}" = indic.code_{submesh.lower()}_1
58
- JOIN
59
- (SELECT distinct("NOM_{mapped_submesh}") as territory_2, "{mapped_submesh}" as territory_2_id, "{mapped_submesh}" from arborescence_geo) arbo2
60
- on arbo2."{mapped_submesh}" = indic.code_{submesh.lower()}_2
61
- """
62
- else:
63
- join_clause = f"""
64
- JOIN
65
- (SELECT distinct("NOM_{mapped_submesh}") as lieu, "{mapped_submesh}" as territoryid, "{mapped_submesh}" from arborescence_geo) arbo
66
- on arbo."{mapped_submesh}" = indic.code_{submesh.lower()}
67
- """
68
- return join_clause
69
-
70
-
71
- def get_table_data_for_geography(
72
- indicator,
73
- territory,
74
- submesh=MeshLevel.Region,
75
- include_place_names=None,
76
- flows=False,
95
+ def get_values_for_indicator_territory_submesh(
96
+ *,
97
+ indicator: Indicator,
98
+ territory: Territory,
99
+ submesh: MeshLevel,
100
+ flows: bool = False,
77
101
  ):
78
- mapped_mesh = "DEPCOM" if territory.mesh == "com" else territory.mesh.upper()
79
- mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
80
-
81
- geo_id_values = "', '".join([id.strip() for id in territory.id.split(",")])
82
-
83
- table_prefix = (
84
- indicator.flows_db_table_prefix if flows else indicator.db_table_prefix
85
- )
86
-
87
- arbo_sub_query = f"""
88
- SELECT DISTINCT("{mapped_submesh}")
89
- FROM arborescence_geo arbo
90
- WHERE arbo."{mapped_mesh}" in('{geo_id_values}')
91
- """
92
-
93
- where = (
94
- f"""
95
- WHERE (indic.code_{submesh.lower()}_1 in ({arbo_sub_query})
96
- OR indic.code_{submesh.lower()}_2 in ({arbo_sub_query}))
102
+ mesh_col = get_mesh_column_name(submesh)
103
+ if submesh == territory.mesh:
104
+ arbo_join = f"""
105
+ JOIN arbo_{submesh} arbo ON arbo.code = indic.{mesh_col} AND arbo.code IN {territory.sql_codes}
97
106
  """
98
- if flows
99
- else f"""
100
- WHERE indic.code_{submesh.lower()} in ({arbo_sub_query})
107
+ else:
108
+ arbo_join = f"""
109
+ JOIN arbo_{territory.mesh}_{submesh} j
110
+ ON j.{submesh} = indic.{mesh_col} AND j.{territory.mesh} IN {territory.sql_codes}
111
+ JOIN arbo_{submesh} arbo
112
+ ON arbo.code = indic.{mesh_col}
113
+ """
114
+ if flows:
115
+ arbo_join = f"""
116
+ JOIN arbo_{territory.mesh}_{submesh} j1
117
+ ON j1.{submesh} = indic.{mesh_col}_1 AND j1.{territory.mesh} IN {territory.sql_codes}
118
+ JOIN arbo_{submesh} arbo1
119
+ ON arbo1.code = indic.{mesh_col}_1
120
+
121
+ JOIN arbo_{territory.mesh}_{submesh} j2
122
+ ON j2.{submesh} = indic.{mesh_col}_2 AND j2.{territory.mesh} IN {territory.sql_codes}
123
+ JOIN arbo_{submesh} arbo2
124
+ ON arbo2.code = indic.{mesh_col}_2
101
125
  """
102
- )
103
126
 
104
127
  return f"""
105
- "{table_prefix}_{submesh.lower()}" indic
106
- {get_place_names_join(include_place_names, mapped_submesh, submesh, flows)}
107
- {where}
128
+ "{indicator.table_name(submesh, flows=flows)}" indic
129
+ {arbo_join}
108
130
  """
109
131
 
110
132
 
111
133
  def calculate_aggregate_values(indicator, with_alternative=True):
112
- # TODO coverage tester avec un indicateur de cette sorte
113
- # Bastien doit exporter des nouvelles données pour faire le test
114
134
  if not indicator.is_composite:
115
135
  return "SUM(valeur) as valeur"
116
136
 
117
- # TODO coverage tester avec un indicateur de cette sorte
118
- # Bastien doit exporter des nouvelles données pour faire le test
119
137
  if indicator.aggregation_function == AggregationFunctions.DISCRETE_COMPONENT_2:
120
138
  sql = f"SUM(composante_1) / COALESCE(NULLIF(SUM(composante_2), 0), 1) * {indicator.aggregation_constant} as valeur"
121
139
  if with_alternative:
@@ -133,45 +151,14 @@ def calculate_aggregate_values(indicator, with_alternative=True):
133
151
  return sql
134
152
 
135
153
 
136
- def get_territories_ids(main_territory_codes, territory_mesh, submesh):
137
- mapped_territory_mesh = (
138
- "DEPCOM" if territory_mesh == "com" else territory_mesh.upper()
139
- )
140
- mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
141
-
142
- query = f"""
143
- SELECT DISTINCT "{mapped_submesh}" as code
144
- FROM arborescence_geo
145
- WHERE "{mapped_territory_mesh}" IN ('{"', '".join(main_territory_codes)}')
146
- """
147
-
148
- territories_ids = [r["code"] for r in run_custom_query(query)]
149
- return territories_ids
150
-
151
-
152
- def get_sub_territories(territory, submesh):
153
- territory_codes = territory.id.split(",")
154
- mapped_territory_mesh = (
155
- "DEPCOM" if territory.mesh == "com" else territory.mesh.upper()
156
- )
157
- mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
158
-
159
- query = f"""
160
- SELECT DISTINCT "{mapped_submesh}" as code, "NOM_{mapped_submesh}" as name
161
- FROM arborescence_geo
162
- WHERE "{mapped_territory_mesh}" IN ('{"', '".join(territory_codes)}')
163
- """
164
-
165
- return run_custom_query(query)
166
-
167
-
168
154
  def get_where_territory(territory):
169
155
  territory_id = (
170
156
  FRANCE_DB_VALUES[territory.id]
171
- if territory.mesh == MeshLevel.National
157
+ if territory.mesh == MeshLevel.fr
172
158
  else territory.id
173
159
  )
174
- return f""" "code_{territory.mesh}" = '{territory_id}' """
160
+ mesh_col = get_mesh_column_name(territory.mesh)
161
+ return f""" "{mesh_col}" = '{territory_id}' """
175
162
 
176
163
 
177
164
  def get_values_for_territory(indicator, territory, filters=None):
@@ -189,7 +176,6 @@ def get_values_for_territory(indicator, territory, filters=None):
189
176
 
190
177
 
191
178
  def get_territory_name(territory):
192
- territory_mesh = "DEPCOM" if territory.mesh == "com" else territory.mesh.upper()
193
- query = f"""SELECT "NOM_{territory_mesh}" as nom FROM arborescence_geo WHERE "{territory_mesh}" = '{territory.id}' LIMIT 1;"""
179
+ query = f"""SELECT name FROM arbo_{territory.mesh} WHERE code IN {territory.sql_codes} LIMIT 1;"""
194
180
  results = run_custom_query(query)
195
- return results[0]["nom"] if results else ""
181
+ return results[0]["name"] if results else ""
@@ -1,6 +1,10 @@
1
1
  from collections import defaultdict
2
2
 
3
- from .commons import add_optional_filters, calculate_aggregate_values
3
+ from .commons import (
4
+ add_optional_filters,
5
+ calculate_aggregate_values,
6
+ get_mesh_column_name,
7
+ )
4
8
  from .utils import run_custom_query
5
9
 
6
10
 
@@ -13,12 +17,13 @@ def get_comparison_values_and_buckets(
13
17
  filters = add_optional_filters(indicator, filters)
14
18
  value = calculate_aggregate_values(indicator, with_alternative=False)
15
19
  number_of_buckets = min(10, len(territories) + len(cmp_territories))
20
+ mesh_col = get_mesh_column_name(submesh)
16
21
  sub_query = f"""
17
22
  SELECT
18
23
  {value},
19
- code_{submesh} as geo_code
24
+ {mesh_col} as geo_code
20
25
  FROM {table_name} indic
21
- WHERE code_{submesh} IN {territories_sql}
26
+ WHERE {mesh_col} IN {territories_sql}
22
27
  AND annee = (
23
28
  SELECT MAX(annee)
24
29
  FROM {table_name}
@@ -5,7 +5,7 @@ from .commons import (
5
5
  add_optional_filters,
6
6
  calculate_aggregate_values,
7
7
  get_last_year,
8
- get_place_names_join,
8
+ get_mesh_column_name,
9
9
  get_where_territory,
10
10
  )
11
11
  from .utils import get_breakdown_dimension, run_custom_query
@@ -23,7 +23,6 @@ def get_proportions_chart(indicator, territory, filters):
23
23
  {add_optional_filters(indicator, filters)}
24
24
  GROUP BY "{breakdown_dimension.db_name}"
25
25
  """
26
-
27
26
  data = run_custom_query(query)
28
27
  filters_color = {f.db_name: f.color for f in breakdown_dimension.filters.all()}
29
28
  data_dict = {
@@ -47,19 +46,15 @@ def get_values_for_submesh_territories(
47
46
  indicator: Indicator, submesh: MeshLevel, territory: Territory, filters
48
47
  ):
49
48
  submesh = submesh.lower()
50
- territory_mesh = "DEPCOM" if territory.mesh == "com" else territory.mesh.upper()
51
- mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
52
-
53
- geo_ids = "', '".join([id.strip() for id in territory.id.split(",")])
49
+ mesh_col = get_mesh_column_name(submesh)
50
+ parent_territory_join = f"JOIN arbo_{territory.mesh}_{submesh} j ON j.{submesh} = arbo.code AND j.{territory.mesh} IN {territory.sql_codes}"
51
+ if submesh == territory.mesh:
52
+ parent_territory_join = f"AND arbo.code IN {territory.sql_codes}"
54
53
  query = f"""
55
- SELECT {calculate_aggregate_values(indicator)}, code_{submesh} as geocode, arbo.lieu as geoname
54
+ SELECT {calculate_aggregate_values(indicator)}, indic.{mesh_col} as geocode, arbo.name as geoname
56
55
  FROM "{indicator.db_table_prefix}_{submesh}" indic
57
- {get_place_names_join(True, mapped_submesh, submesh)}
58
- WHERE code_{submesh} IN (
59
- SELECT DISTINCT("{mapped_submesh}")
60
- FROM arborescence_geo arbo
61
- WHERE arbo."{territory_mesh}" IN ('{geo_ids}')
62
- )
56
+ JOIN arbo_{submesh} arbo ON arbo.code = indic.{mesh_col}
57
+ {parent_territory_join}
63
58
  {add_optional_filters(indicator, filters)}
64
59
  AND annee = (
65
60
  SELECT MAX(annee)
@@ -77,7 +77,6 @@ def get_indicator_histogram_data(indicator, territory, submesh, filters):
77
77
  territory_values = get_values_for_submesh_territories(
78
78
  indicator, submesh, territory, filters
79
79
  )
80
- print("!!", territory_values)
81
80
  datasets_histogram_bar_chart, deciles = get_territories_histogram_data(
82
81
  territory_values, indicator.unite
83
82
  )
@@ -1,4 +1,7 @@
1
- from .commons import generate_aggregate_query_for_location
1
+ from .commons import (
2
+ generate_aggregate_query_for_location,
3
+ get_mesh_column_name,
4
+ )
2
5
  from .utils import run_custom_query
3
6
 
4
7
 
@@ -29,15 +32,16 @@ def get_min_max_statistics(indicator, submesh):
29
32
 
30
33
 
31
34
  def get_values_for(extremum, submesh, is_alternative=False):
35
+ mesh_col = get_mesh_column_name(submesh)
32
36
  return f"""
33
37
  {extremum}_value,
34
38
  (
35
- SELECT code_{submesh} AS code_{extremum}
39
+ SELECT {mesh_col} AS code_{extremum}
36
40
  FROM aggregat
37
41
  WHERE valeur{"_alternative" if is_alternative else ""} = (SELECT * FROM {extremum}_value) LIMIT 1
38
42
  ) AS code_{extremum},
39
43
  (
40
- SELECT count(code_{submesh}) AS count_{extremum}
44
+ SELECT count({mesh_col}) AS count_{extremum}
41
45
  FROM aggregat
42
46
  WHERE valeur{"_alternative" if is_alternative else ""} = (SELECT * FROM {extremum}_value)
43
47
  ) AS count_{extremum},
@@ -73,12 +77,13 @@ def get_names_from_codes(dict_result, submesh):
73
77
  for key, value in dict_result.items():
74
78
  if key.startswith("code_"):
75
79
  codes_to_fetch.append(value)
76
- mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
80
+ codes = ", ".join(f"'{code.strip()}'" for code in codes_to_fetch)
77
81
  query = f"""
78
- SELECT DISTINCT "{mapped_submesh}" as code, "NOM_{mapped_submesh}" as name
79
- FROM arborescence_geo
80
- WHERE "{mapped_submesh}" IN ({", ".join(["'" + c + "'" for c in codes_to_fetch])});
82
+ SELECT code, name
83
+ FROM arbo_{submesh}
84
+ WHERE code IN ({codes});
81
85
  """
86
+
82
87
  rows = run_custom_query(query)
83
88
  names_dict = {}
84
89
  for row in rows:
@@ -4,7 +4,8 @@ from .commons import (
4
4
  add_optional_filters,
5
5
  calculate_aggregate_values,
6
6
  get_last_year,
7
- get_table_data_for_geography,
7
+ get_mesh_column_name,
8
+ get_values_for_indicator_territory_submesh,
8
9
  )
9
10
  from .utils import get_breakdown_dimension, run_custom_query
10
11
 
@@ -14,29 +15,30 @@ def breakdown_territories(indicator, submesh, year, filters, top_10_territories)
14
15
  [f"'{territory['code_geo']}'" for territory in top_10_territories]
15
16
  )
16
17
  breakdown_dimension = get_breakdown_dimension(indicator).db_name
17
-
18
+ mesh_col = get_mesh_column_name(submesh)
18
19
  query = f"""
19
20
  SELECT {calculate_aggregate_values(indicator, with_alternative=False)},
20
21
  "{breakdown_dimension}" as dimension,
21
- "code_{submesh}" as code_geo
22
+ "{mesh_col}" as code_geo
22
23
  FROM "{indicator.db_table_prefix}_{submesh}" as indic
23
- WHERE code_{submesh} in ({territories_code}) AND annee = {year}
24
+ WHERE {mesh_col} in ({territories_code}) AND annee = {year}
24
25
  {add_optional_filters(indicator, filters)}
25
- GROUP BY "code_{submesh}", "{breakdown_dimension}"
26
+ GROUP BY "{mesh_col}", "{breakdown_dimension}"
26
27
  """
27
28
  results = run_custom_query(query)
28
29
  return results
29
30
 
30
31
 
31
32
  def get_top_10_territories(indicator, territory, submesh, year, filters):
33
+ mesh_col = get_mesh_column_name(submesh)
32
34
  query = f"""
33
35
  SELECT {calculate_aggregate_values(indicator, with_alternative=False)},
34
- indic.code_{submesh} as code_geo, arbo.lieu as lieu
35
- FROM {get_table_data_for_geography(indicator, territory, submesh, include_place_names=True)}
36
+ indic.{mesh_col} as code_geo, arbo.name
37
+ FROM {get_values_for_indicator_territory_submesh(indicator=indicator, territory=territory, submesh=submesh)}
36
38
  {add_optional_filters(indicator, filters)}
37
39
  AND annee = {year}
38
40
  AND valeur IS NOT NULL
39
- GROUP BY code_{submesh}, arbo.lieu
41
+ GROUP BY indic.{mesh_col}, arbo.name
40
42
  ORDER BY valeur DESC
41
43
  LIMIT 10
42
44
  """
@@ -78,8 +80,6 @@ def get_indicator_top_10_data(indicator, territory, submesh, filters):
78
80
  }
79
81
  for f in breakdown_filters
80
82
  ]
81
- # TODO coverage faire un test avec un indicateur qui n'a pas de dimensions
82
- # necessite un export de données de Bastien
83
83
  else:
84
84
  datasets_top_bar_chart = [
85
85
  {
@@ -88,12 +88,12 @@ def get_indicator_top_10_data(indicator, territory, submesh, filters):
88
88
  }
89
89
  ]
90
90
 
91
- labels_top_bar_chart = [territory["lieu"] for territory in territories]
91
+ labels_top_bar_chart = [territory["name"] for territory in territories]
92
92
 
93
93
  csv_data = []
94
94
  for territory in territories:
95
95
  csv_row = {}
96
- csv_row["Territoire"] = territory["lieu"]
96
+ csv_row["Territoire"] = territory["name"]
97
97
  csv_row["Code Géographique"] = territory["code_geo"]
98
98
  csv_row[f"Valeur {indicator.unite}"] = territory["valeur"]
99
99
  if breakdown_dimension:
@@ -2,6 +2,15 @@ from django.conf import settings
2
2
  from django.db import connections
3
3
 
4
4
 
5
+ def format_sql_codes(codes: list[str]):
6
+ """
7
+ Format list of IDs for SQL IN statement.
8
+ ["1","2","3"] => ('1', '2', '3')
9
+ """
10
+ codes = ", ".join(f"'{code.strip()}'" for code in codes)
11
+ return f"({codes})"
12
+
13
+
5
14
  def get_breakdown_dimension(indicator):
6
15
  breakdown_dimension = (
7
16
  indicator.dimensions.filter(is_breakdown=True).first()
@@ -1,5 +1,8 @@
1
1
  from .payloads import IndicatorTablePayload
2
- from .query.commons import add_optional_filters, get_table_data_for_geography
2
+ from .query.commons import (
3
+ add_optional_filters,
4
+ get_values_for_indicator_territory_submesh,
5
+ )
3
6
  from .query.utils import run_custom_query
4
7
 
5
8
 
@@ -22,10 +25,10 @@ def _get_query(
22
25
  )
23
26
  )
24
27
  territory_search_where = (
25
- "OR (unaccent(LOWER(territory_1)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%')))) OR (unaccent(LOWER(territory_2)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
28
+ "OR (unaccent(LOWER(arbo1.name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%')))) OR (unaccent(LOWER(arbo2.name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
26
29
  if props.flows
27
30
  else (
28
- "OR (unaccent(LOWER(lieu)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
31
+ "OR (unaccent(LOWER(name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
29
32
  )
30
33
  )
31
34
  where = (
@@ -48,7 +51,7 @@ def _get_query(
48
51
  SELECT
49
52
  {", ".join(columns)}
50
53
  FROM
51
- {get_table_data_for_geography(indicator, props.territory, props.submesh, True, props.flows)}
54
+ {get_values_for_indicator_territory_submesh(indicator=indicator, territory=props.territory, submesh=props.submesh, flows=props.flows)}
52
55
  {regular_dimensions_filters}
53
56
  {where} {where_year}
54
57
  {order_clause}
@@ -60,18 +63,18 @@ def get_values_columns(indicator, props, *, for_export=False):
60
63
  if props.flows:
61
64
  columns = [
62
65
  "annee",
63
- "territory_1",
64
- "territory_2",
66
+ "arbo1.name as territory_1",
67
+ "arbo2.name as territory_2",
65
68
  f"{indicator.flows_dimension} AS dimension"
66
69
  if indicator.flows_dimension
67
70
  else None,
68
71
  "CAST(valeur AS int) as valeur",
69
72
  ]
70
73
  if for_export:
71
- columns += ["territory_1_id", "territory_2_id"]
74
+ columns += ["arbo1.code as territory_1_id", "arbo2.code as territory_2_id"]
72
75
  else:
73
76
  columns = (
74
- ["annee", "lieu"]
77
+ ["annee", "name"]
75
78
  + [f"{dimension.db_name}" for dimension in indicator.dimensions.all()]
76
79
  + [
77
80
  f"valeur * {indicator.aggregation_constant if indicator.unite == '%' else 1} AS valeur",
@@ -81,17 +84,17 @@ def get_values_columns(indicator, props, *, for_export=False):
81
84
  ]
82
85
  )
83
86
  if for_export:
84
- columns += ["territoryid"]
87
+ columns += ["code"]
85
88
  return columns
86
89
 
87
90
 
88
91
  def get_values_orders(indicator, props: IndicatorTablePayload):
89
92
  territory_order = None
90
- if props.column_order not in ["lieu", "territory_1", "territory_2"]:
93
+ if props.column_order not in ["name", "arbo1.name", "arbo2.name"]:
91
94
  territory_order = (
92
- "LOWER(territory_1) ASC, LOWER(territory_2) ASC"
95
+ "LOWER(arbo1.name) ASC, LOWER(arbo2.name) ASC"
93
96
  if props.flows
94
- else "LOWER(lieu) ASC"
97
+ else "LOWER(name) ASC"
95
98
  )
96
99
  year_order = "annee DESC" if props.column_order != "annee" else None
97
100
  dimension_order = None