Skip to content

Commit e936b1f

Browse files
committed
URL de debug + tweak connection DB
1 parent 9e333b3 commit e936b1f

File tree

7 files changed

+151
-47
lines changed

7 files changed

+151
-47
lines changed

django/core/models.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class EventImpact(StrEnum):
148148

149149
class ProcedureQuerySet(models.QuerySet):
150150
def with_events(self) -> Self:
151+
# FIXME : Il va falloir individualiser cela ?
151152
approbation_event_types = [
152153
event_type
153154
for lol in EVENT_IMPACT_BY_TYPE_DOCUMENT.values()
@@ -391,6 +392,20 @@ def departement(self, departement: str | None = None) -> list["CommuneProcedure"
391392
a.append(perim)
392393
return a
393394

395+
# FIXME: Non testé
396+
def collectivite(
397+
self, collectivite_code: str, collectivite_type: str
398+
) -> list["CommuneProcedure"]:
399+
perimetres = self.prefetch_related(
400+
models.Prefetch("procedure", Procedure.objects.all())
401+
).filter(
402+
collectivite_code=collectivite_code, collectivite_type=collectivite_type
403+
)
404+
405+
for perim in perimetres:
406+
perim.opposable = perim._opposable(perimetres)
407+
return perimetres
408+
394409

395410
class CommuneProcedure(models.Model):
396411
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
@@ -430,15 +445,6 @@ def _opposable(self, all_perims: list[Self]) -> bool:
430445
"created_at", # FIXME Test created_at order
431446
),
432447
)
433-
if (
434-
self.collectivite_code == "24183"
435-
and str(self.procedure.id) == "4c4cb7e7-f660-40d8-8cc5-9b6a34cfb741"
436-
): # FIXME COMD 05001 cf448ad5-193b-4c1f-a38b-d92a9b4472e6
437-
for p in procedures_opposables:
438-
if p.is_principale:
439-
logging.warning(
440-
f"{p.id=!s} {p.date_approbation=} {p.created_at=!s}" # noqa: G004
441-
)
442448
if not procedures_opposables:
443449
return False
444450
return procedures_opposables[-1].id == self.procedure_id

django/core/settings.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,8 @@
6363
DATABASES = {
6464
"default": {
6565
**env.db("DATABASE_URL"),
66-
"OPTIONS": {
67-
"pool": {
68-
"min_size": 1,
69-
}
70-
},
66+
"CONN_MAX_AGE": env.int("CONN_MAX_AGE", 0),
67+
"CONN_HEALTH_CHECK": True,
7168
}
7269
}
7370

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta name="color-scheme" content="dark light" />
7+
8+
<title>Document</title>
9+
</head>
10+
<body>
11+
<h1>{{ collectivite.code }} {{ collectivite.intitule }}</h1>
12+
{% regroup cp by procedure.is_schema as wesh %}
13+
{% for wes, procedures in wesh %}
14+
{{ wes }}
15+
<table>
16+
<tr>
17+
<th>P</th>
18+
<th>Opposable</th>
19+
<th>Statut</th>
20+
<th>Date d'approbation</th>
21+
</tr>
22+
{% for procedure in procedures %}
23+
<tr>
24+
<td>
25+
<a href="{{ procedure.procedure.get_absolute_url }}">
26+
{{ procedure.procedure }}
27+
</a>
28+
<br />
29+
{{ procedure.procedure_id }}
30+
</td>
31+
<td>{{ procedure.opposable }}</td>
32+
<td>{{ procedure.procedure.statut }}</td>
33+
<td>{{ procedure.procedure.date_approbation }}</td>
34+
</tr>
35+
{% endfor %}
36+
</table>
37+
{% endfor %}
38+
</body>
39+
</html>

django/core/tests/manual_test_e2e.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,46 @@ def django_db_setup(django_db_modify_db_settings: None) -> None:
3131
connections["default"] = connections.create_connection("default")
3232

3333

34+
DATE_DAPPROBATION_MAL_DETECTEE = [
35+
("09106", "93de19ac-d609-4b26-8651-6c43ed5a2a8a"),
36+
("09106", "51ded599-7b22-44ca-b740-bf8b7475f266"),
37+
("09168", "93de19ac-d609-4b26-8651-6c43ed5a2a8a"),
38+
("09168", "5f8cf12b-4d7a-4ad6-a30e-5c10c2421ba5"),
39+
("09249", "93de19ac-d609-4b26-8651-6c43ed5a2a8a"),
40+
("09249", "da8a2cca-e609-41ee-948d-5b492793dead"),
41+
("09305", "93de19ac-d609-4b26-8651-6c43ed5a2a8a"),
42+
("09305", "8724af17-193f-44a7-80c4-ce7469866b86"),
43+
("12066", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
44+
("12066", "5bdf7888-9b63-4a32-983f-7fe55a3c5ab0"),
45+
("12076", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
46+
("12076", "027741b2-9d93-4606-94fb-43dca8655ba5"),
47+
("12138", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
48+
("12138", "76d95ba8-510c-4bfc-b7d8-f49d3e4bc822"),
49+
("12161", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
50+
("12161", "761923eb-ef9a-4836-809a-8fef427aba9c"),
51+
("12165", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
52+
("12165", "da0a633d-2570-4ceb-9090-699f6eaf3d40"),
53+
("12215", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
54+
("12215", "c0d393f7-bae3-4a6f-b83c-3d4f6c0d5769"),
55+
("12221", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
56+
("12221", "d6bda473-bbb4-4dae-9fac-14fe9bcbd60f"),
57+
("12254", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
58+
("12254", "9b13518b-8b4d-469c-b0b2-32b5af930342"),
59+
("12288", "2940c934-d3f2-43d4-8678-21a9c3a5e3db"),
60+
("12288", "e28018e0-6306-4c0d-a74c-ebdc7c2386e8"),
61+
("14365", "2f9b15b9-81fd-4634-8be9-119d41e0c45f"),
62+
("14365", "f58c3625-b5b3-45a5-aff1-c47c99822518"),
63+
]
64+
65+
PROCEDURE_DABROGATION = [
66+
("15006", "475f2868-afb8-4dc9-8ca4-06e5a6a49333"),
67+
("15006", "506775b3-abdf-4e5b-b73b-0d882363ebd7"),
68+
]
3469
LEGITIMATE_DIFFERENCES = [
3570
# df2439d9-ba4f-4cba-9fcf-c8ed3a52b24c est un SCoT opposable mais pas pour 01155
3671
("01155", "40e4f479-d0f1-4d2d-9f80-6760c44b22e5"),
37-
(),
72+
*DATE_DAPPROBATION_MAL_DETECTEE,
73+
*PROCEDURE_DABROGATION,
3874
]
3975

4076

@@ -98,7 +134,8 @@ def Ztest_all(
98134
),
99135
)
100136

101-
@pytest.mark.parametrize("departement", [f"{i:0>2}" for i in range(9, 10)])
137+
# FIXME Ne pas oublier la corse
138+
@pytest.mark.parametrize("departement", [f"{i:0>2}" for i in range(24, 25)])
102139
@pytest.mark.django_db
103140
def test_departement(
104141
self,
@@ -120,6 +157,7 @@ def test_departement(
120157
"/api/perimetres",
121158
query_params={"departement": departement, "limit": limit},
122159
)
160+
logging.warning(response.resolver_match)
123161
logging.warning((datetime.now() - before) / timedelta(milliseconds=1))
124162

125163
django = pl.read_csv(
@@ -155,7 +193,7 @@ def test_departement(
155193
nuxt_row["procedure_id"],
156194
) in LEGITIMATE_DIFFERENCES:
157195
logging.warning(f"Ignoring {nuxt_row['procedure_id']}") # noqa: G004
158-
continue
159-
160-
assert nuxt_row == django_row
196+
assert nuxt_row != django_row
197+
else:
198+
assert nuxt_row == django_row
161199
# polars.testing.assert_frame_equal(nuxt, django)

django/core/tests/test_models.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,63 +52,72 @@ def test_is_schema(self) -> None:
5252
assert Procedure(type_document=TypeDocument.SD).is_schema
5353

5454
@pytest.mark.django_db
55-
def test_plus_recent_event_prescription(
55+
def test_date_approbation_retourne_plus_recent_event_approbation(
5656
self, django_assert_num_queries: DjangoAssertNumQueries
5757
) -> None:
5858
procedure = Procedure.objects.create(type_document=TypeDocument.PLUI)
5959
procedure.event_set.create(
60-
type="Délibération de prescription du conseil municipal ou communautaire",
60+
type="Caractère exécutoire",
6161
date_iso="2022-12-01",
6262
)
63-
event_prescription = procedure.event_set.create(
64-
type="Délibération de prescription du conseil municipal ou communautaire",
63+
procedure.event_set.create(
64+
type="Délibération d'approbation du municipal ou communautaire",
6565
date_iso="2024-12-01",
6666
)
6767
procedure.event_set.create(
68-
type="Délibération de prescription du conseil municipal ou communautaire",
68+
type="Délibération d'approbation",
6969
date_iso="2023-12-01",
7070
)
7171

72-
assert event_prescription.impact == EventImpact.EN_COURS
72+
# FIXME More checks
73+
assert [event.impact for event in procedure.event_set.all()] == [
74+
EventImpact.OPPOSABLE,
75+
EventImpact.OPPOSABLE,
76+
EventImpact.OPPOSABLE,
77+
]
7378
with django_assert_num_queries(1):
7479
procedure_with_events = Procedure.objects.with_events().get(id=procedure.id)
7580

76-
assert procedure_with_events.date_prescription == "2024-12-01"
81+
assert procedure_with_events.date_approbation == "2024-12-01"
7782

7883
@pytest.mark.django_db
79-
def test_event_prescription_uniquement(
84+
def test_date_approbation_ignore_event_pas_approbation(
8085
self, django_assert_num_queries: DjangoAssertNumQueries
8186
) -> None:
8287
procedure = Procedure.objects.create(type_document=TypeDocument.PLUI)
8388
procedure.event_set.create(
84-
type="Caractère exécutoire",
85-
date_iso="2025-12-01",
86-
)
87-
event_prescription = procedure.event_set.create(
8889
type="Délibération de prescription du conseil municipal ou communautaire",
90+
date_iso="2023-12-01",
91+
)
92+
event_approbation = procedure.event_set.create(
93+
type="Caractère exécutoire",
8994
date_iso="2024-12-01",
9095
)
9196
procedure.event_set.create(
92-
type="Caractère exécutoire",
97+
type="Délibération de prescription du conseil municipal ou communautaire",
9398
date_iso="2025-12-01",
9499
)
95100

96-
assert event_prescription.impact == EventImpact.EN_COURS
101+
assert [event.impact for event in procedure.event_set.all()] == [
102+
EventImpact.EN_COURS,
103+
EventImpact.OPPOSABLE,
104+
EventImpact.EN_COURS,
105+
]
97106
with django_assert_num_queries(1):
98107
procedure_with_events = Procedure.objects.with_events().get(id=procedure.id)
99108

100-
assert procedure_with_events.date_prescription == "2024-12-01"
109+
assert procedure_with_events.date_approbation == "2024-12-01"
101110

102111
@pytest.mark.django_db
103-
def test_event_prescription_manquant(
112+
def test_date_approbation_quand_event_approbation_manquant(
104113
self, django_assert_num_queries: DjangoAssertNumQueries
105114
) -> None:
106115
procedure = Procedure.objects.create(type_document=TypeDocument.PLUI)
107116

108117
with django_assert_num_queries(1):
109118
procedure_with_events = Procedure.objects.with_events().get(id=procedure.id)
110119

111-
assert procedure_with_events.date_prescription == "0000-00-00"
120+
assert procedure_with_events.date_approbation == "0000-00-00"
112121

113122

114123
class TestProcedureStatut:
@@ -233,10 +242,8 @@ def test_plus_recente_opposable(
233242
is_principale=True, type_document=TypeDocument.PLUI
234243
)
235244
procedure_opposable.event_set.create(
236-
type="Délibération de prescription du conseil municipal ou communautaire",
237-
date_iso="2024-12-01",
245+
type="Caractère exécutoire", date_iso="2024-12-01"
238246
)
239-
procedure_opposable.event_set.create(type="Caractère exécutoire")
240247
commune_procedure_opposable = procedure_opposable.perimetre.create(
241248
collectivite_code="12345", departement="12"
242249
)
@@ -245,11 +252,7 @@ def test_plus_recente_opposable(
245252
is_principale=True, type_document=TypeDocument.PLU
246253
)
247254
procedure_precedente.event_set.create(
248-
type="Délibération de prescription du conseil municipal ou communautaire",
249-
date_iso="2023-12-01",
250-
)
251-
procedure_precedente.event_set.create(
252-
type="Caractère exécutoire",
255+
type="Caractère exécutoire", date_iso="2023-12-01"
253256
)
254257
commune_procedure_precedente = procedure_precedente.perimetre.create(
255258
collectivite_code="12345", departement="12"

django/core/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99
urlpatterns = [
1010
path("_admin/", admin.site.urls),
11+
path("collectivite/<collectivite_code>/", views.collectivite),
1112
path("api/perimetres", views.perimetres),
1213
path("__reload__/", include("django_browser_reload.urls")),
13-
re_path(r"(?P<path>.*)", ProxyView.as_view(upstream=settings.UPSTREAM_NUXT)),
1414
*debug_toolbar_urls(),
15+
re_path(r"(?P<path>.*)", ProxyView.as_view(upstream=settings.UPSTREAM_NUXT)),
1516
]

django/core/views.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from csv import DictWriter
2+
from operator import attrgetter
23

34
from django.http import HttpRequest, HttpResponse
5+
from django.shortcuts import render
46

5-
from core.models import CommuneProcedure
7+
from core.models import CommuneProcedure, communes
68

79

810
def _format_perimetre(perimetre: dict) -> dict:
@@ -22,7 +24,7 @@ def perimetres(request: HttpRequest) -> HttpResponse:
2224
procedure__is_principale=True
2325
).departement(departement)
2426

25-
response = HttpResponse(content_type="text/html;charset=utf-8")
27+
response = HttpResponse(content_type="text/csv;charset=utf-8")
2628
csv_writer = DictWriter(
2729
response,
2830
dialect="unix",
@@ -41,3 +43,21 @@ def perimetres(request: HttpRequest) -> HttpResponse:
4143
csv_writer.writerow(a)
4244

4345
return response
46+
47+
48+
def collectivite(
49+
request: HttpRequest, collectivite_code: str, collectivite_type: str = "COM"
50+
) -> HttpResponse:
51+
communes_procedures = CommuneProcedure.objects.filter(
52+
procedure__is_principale=True
53+
).collectivite(collectivite_code, collectivite_type)
54+
communes_procedures = sorted(
55+
communes_procedures,
56+
key=attrgetter("procedure.is_schema", "procedure.date_approbation"),
57+
reverse=True,
58+
)
59+
60+
commune = communes[f"{collectivite_code}_{collectivite_type}"]
61+
return render(
62+
request, "collectivite.html", {"collectivite": commune, "cp": communes_procedures}
63+
)

0 commit comments

Comments
 (0)