loko/streetup/assets/migrations/0013_update_rwi_assets_codification.py
2026-07-22 14:48:40 +02:00

169 lines
5.8 KiB
Python

from django.db import migrations
def update_rwi_codes(apps, schema_editor):
NatureRWIAsset = apps.get_model('assets', 'NatureRWIAsset')
# We try-catch the GuidedOperationData import because it's in another app,
# and we want to ensure robust execution.
try:
GuidedOperationData = apps.get_model('interventions', 'GuidedOperationData')
except LookupError:
GuidedOperationData = None
# Mappings from structure type to acronym
mappings = {
'avaloir': 'AV',
'bordure sequencee': 'BS',
'bouche injection': 'BI',
'clapet anti-retour': 'CA',
'empierrement sedimentation': 'ES',
'kerb cell': 'KC',
'puits infiltration': 'PI',
'surverse': 'SU',
'vanne isolation': 'VI',
'vanne regulation': 'VR',
'gargouille de trottoir': 'GT',
'filet eau': 'FE',
'avaloir de rail': 'AR',
'bordure arasee': 'BA',
'caniveau infiltrant': 'CI',
'drain': 'D',
'trop plein': 'TP',
'reseau egout separatif': 'RES',
'bassin sec/infiltration': 'OED',
'bassin en eau': 'OED',
'fosse': 'EVC',
'jardin de pluie': 'EVC',
'noue': 'EVC',
'massif drainant': 'OED',
'tranchee drainante': 'OED',
'toiture stockante': 'OSI',
'toiture verte': 'OSI',
'bassin orage': 'OED',
'SAUL-vide': 'OED',
'SAUL-terre': 'TA',
'citerne': 'OED',
'espace vert sur dalle': 'EVC',
'bande filtrante': 'EVC',
'collecteur en beton poreux': 'OED',
'chambre de visite': 'CV',
}
code_updates = {}
for asset in NatureRWIAsset.objects.all():
old_code = asset.code
# Calculate acronym
struct_type_lower = asset.structure_type.strip().lower() if asset.structure_type else None
acronym = None
if asset.code_name:
acronym = asset.code_name.strip().upper()
elif struct_type_lower in mappings:
acronym = mappings[struct_type_lower]
elif asset.geometry_type:
acronym = asset.geometry_type.upper()
else:
acronym = 'UNK'
fid = asset.external_id or asset.id
new_code = f"RWI_{acronym}_{fid:03d}"
if old_code != new_code:
asset.code = new_code
if asset.name_fr == old_code:
asset.name_fr = new_code
if asset.name_nl == old_code:
asset.name_nl = new_code
asset.save(update_fields=['code', 'name_fr', 'name_nl'])
code_updates[old_code] = new_code
# Update GuidedOperationData JSON references
if GuidedOperationData and code_updates:
for gd in GuidedOperationData.objects.all():
modified = False
data = gd.data
if not isinstance(data, dict):
continue
def replace_codes(obj):
nonlocal modified
if isinstance(obj, dict):
for k, v in list(obj.items()):
if k == 'rwi_asset_code' and v in code_updates:
obj[k] = code_updates[v]
modified = True
else:
replace_codes(v)
elif isinstance(obj, list):
for item in obj:
replace_codes(item)
replace_codes(data)
if modified:
gd.data = data
gd.save(update_fields=['data'])
def reverse_rwi_codes(apps, schema_editor):
NatureRWIAsset = apps.get_model('assets', 'NatureRWIAsset')
try:
GuidedOperationData = apps.get_model('interventions', 'GuidedOperationData')
except LookupError:
GuidedOperationData = None
code_updates_reverse = {}
for asset in NatureRWIAsset.objects.all():
old_code = asset.code
# Calculate old format: RWI_{geometry_type.upper()}_{external_id:03d}
geom_type_upper = asset.geometry_type.upper() if asset.geometry_type else 'POLYGON'
fid = asset.external_id or asset.id
original_code = f"RWI_{geom_type_upper}_{fid:03d}"
if old_code != original_code:
asset.code = original_code
if asset.name_fr == old_code:
asset.name_fr = original_code
if asset.name_nl == old_code:
asset.name_nl = original_code
asset.save(update_fields=['code', 'name_fr', 'name_nl'])
code_updates_reverse[old_code] = original_code
# Revert GuidedOperationData JSON references
if GuidedOperationData and code_updates_reverse:
for gd in GuidedOperationData.objects.all():
modified = False
data = gd.data
if not isinstance(data, dict):
continue
def replace_codes(obj):
nonlocal modified
if isinstance(obj, dict):
for k, v in list(obj.items()):
if k == 'rwi_asset_code' and v in code_updates_reverse:
obj[k] = code_updates_reverse[v]
modified = True
else:
replace_codes(v)
elif isinstance(obj, list):
for item in obj:
replace_codes(item)
replace_codes(data)
if modified:
gd.data = data
gd.save(update_fields=['data'])
class Migration(migrations.Migration):
dependencies = [
('assets', '0012_trafficlightintersection_is_radar'),
]
operations = [
migrations.RunPython(update_rwi_codes, reverse_rwi_codes),
]