Skip to content

Commit 3629662

Browse files
authored
Ensure consistency and follow db constraints while importing new data. (#2390)
When switching a parent value to a value not displaying child, it now reinit the child to their initial value. For example, if a record in db has entree_plain_pied=False, entree_ascenceur=True, if we import a line saying entree_plain_pied=True, then we now switch to entree_ascenceur=None
1 parent 2fb9214 commit 3629662

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

erp/imports/serializers.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from erp.imports.utils import get_address_query_to_geocode
99
from erp.models import Accessibilite, Activite, Commune, Erp, ExternalSource
1010
from erp.provider import geocoder, sirene
11+
from erp.schema import FIELDS
1112

1213
TRUE_VALUES = ["true", "True", "TRUE", "1", "vrai", "Vrai", "VRAI", "oui", "Oui", "OUI", True]
1314
FALSE_VALUES = ["false", "False", "FALSE", "0", "faux", "Faux", "FAUX", "non", "Non", "NON", False]
@@ -211,6 +212,25 @@ def validate_accessibilite(self, obj):
211212

212213
return obj
213214

215+
def _handle_children_reinit(self, accessibilite_instance, field_name):
216+
field_config = FIELDS.get(field_name)
217+
if not field_config or not field_config.get("children"):
218+
return
219+
220+
current_value = getattr(accessibilite_instance, field_name)
221+
trigger_values = field_config.get("value_to_display_children", [])
222+
223+
if str(current_value) not in trigger_values:
224+
for child_name in field_config.get("children"):
225+
field_obj = accessibilite_instance._meta.get_field(child_name)
226+
default_value = field_obj.get_default()
227+
if callable(default_value):
228+
default_value = default_value()
229+
230+
setattr(accessibilite_instance, child_name, default_value)
231+
232+
self._handle_children_reinit(accessibilite_instance, child_name)
233+
214234
def validate(self, obj):
215235
if "accessibilite" not in obj:
216236
raise serializers.ValidationError("Veuillez fournir les données d'accessibilité.")
@@ -307,8 +327,10 @@ def update(self, instance, validated_data, partial=True):
307327
if enrich_only and getattr(accessibilite, attr, None) is not None:
308328
continue
309329

310-
if validated_data["accessibilite"][attr] not in (None, [], ()):
311-
setattr(accessibilite, attr, validated_data["accessibilite"][attr])
330+
new_value = validated_data["accessibilite"][attr]
331+
if new_value not in (None, [], ()):
332+
setattr(accessibilite, attr, new_value)
333+
self._handle_children_reinit(accessibilite, attr)
312334

313335
accessibilite.save()
314336

tests/erp/imports/test_serializers.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,51 @@ def test_erp_update_serializer():
134134
assert erp.accessibilite.accueil_audiodescription == ["avec_app"]
135135

136136

137+
@pytest.mark.django_db
138+
def test_erp_update_serializer_inconsistencies():
139+
erp = ErpFactory(
140+
nom="Initial name",
141+
accessibilite__accueil_audiodescription_presence=True,
142+
accessibilite__accueil_audiodescription=["avec_app"],
143+
accessibilite__entree_plain_pied=False,
144+
accessibilite__entree_ascenseur=True,
145+
accessibilite__entree_ascenseur_pmr=True,
146+
accessibilite__accueil_chambre_nombre_accessibles=1,
147+
accessibilite__accueil_chambre_douche_siege=True,
148+
accessibilite__accueil_cheminement_plain_pied=False, # control
149+
accessibilite__accueil_cheminement_ascenseur=True, # control
150+
accessibilite__accueil_cheminement_ascenseur_pmr=True, # control
151+
)
152+
153+
serializer = ErpImportSerializer(
154+
instance=erp,
155+
data={
156+
"accessibilite": {
157+
"accueil_audiodescription_presence": False,
158+
"entree_plain_pied": True,
159+
"accueil_chambre_nombre_accessibles": 0,
160+
},
161+
"nom": "Aux bons pains",
162+
},
163+
partial=True,
164+
)
165+
assert serializer.is_valid(), serializer.errors
166+
serializer.save()
167+
168+
erp.refresh_from_db()
169+
assert erp.nom != "Aux bons pains", "Name should not be editable"
170+
assert erp.accessibilite.accueil_audiodescription_presence is False
171+
assert erp.accessibilite.accueil_audiodescription == [], "should have reinit child of attr switched to False"
172+
assert erp.accessibilite.entree_plain_pied is True
173+
assert erp.accessibilite.entree_ascenseur is None, "should have reinit child"
174+
assert erp.accessibilite.entree_ascenseur_pmr is None, "should have reinit child of child"
175+
assert erp.accessibilite.accueil_chambre_nombre_accessibles == 0
176+
assert erp.accessibilite.accueil_chambre_douche_siege is None, "should have reinit child of attr switched to 0"
177+
assert erp.accessibilite.accueil_cheminement_plain_pied is False, "control, should not be reinit"
178+
assert erp.accessibilite.accueil_cheminement_ascenseur is True, "control, should not be reinit"
179+
assert erp.accessibilite.accueil_cheminement_ascenseur_pmr is True, "control, should not be reinit"
180+
181+
137182
@pytest.mark.django_db
138183
def test_erp_duplicate():
139184
boulangerie = ActiviteFactory(nom="Boulangerie")

0 commit comments

Comments
 (0)