loko/streetup/assets/management/commands/transfer_prevention_radars.py
2026-07-22 14:48:40 +02:00

194 lines
8.8 KiB
Python

from django.core.management.base import BaseCommand
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
from assets.models import (
ITSGeoAsset,
ITSGeoAssetContract,
ITSAssetModel,
TrafficLightIntersection,
TrafficLightRadarModel,
TrafficLightRadar,
TrafficLightContract,
AssetCategory
)
from common.models import Thematic
from interventions.models import (
Intervention,
InterventionAsset,
InterventionLocation
)
class Command(BaseCommand):
help = "Transfer prevention radars from the ITS thematic to the Traffic Lights thematic."
def handle(self, *args, **options):
# 1. Retrieve all prevention radars in ITSGeoAsset
its_radars = ITSGeoAsset.objects.filter(code__startswith='RAD_PREV_')
total_radars = its_radars.count()
self.stdout.write(f"Found {total_radars} prevention radars starting with 'RAD_PREV_' in ITSGeoAsset.")
if total_radars == 0:
self.stdout.write(self.style.WARNING("No prevention radars to transfer. Exiting."))
return
# 2. Get necessary content types and thematics
its_geo_asset_ct = ContentType.objects.get_for_model(ITSGeoAsset)
traffic_light_radar_ct = ContentType.objects.get_for_model(TrafficLightRadar)
traffic_light_intersection_ct = ContentType.objects.get_for_model(TrafficLightIntersection)
try:
trafficlights_thematic = Thematic.objects.get(code='trafficlights')
except Thematic.DoesNotExist:
self.stdout.write(self.style.ERROR("Thematic 'trafficlights' not found. Exiting."))
return
try:
radar_category = AssetCategory.objects.get(code='TL_RADAR_PREVENTIF')
except AssetCategory.DoesNotExist:
try:
radar_category = AssetCategory.objects.get(id=20)
except AssetCategory.DoesNotExist:
radar_category = AssetCategory.objects.filter(name_fr='Radar Préventif').first()
if not radar_category:
self.stdout.write(self.style.ERROR("AssetCategory 'Radar Préventif' (code TL_RADAR_PREVENTIF) not found. Exiting."))
return
# We will keep track of models mapped, locations created/retrieved, radars created, interventions updated, contracts migrated
transferred_count = 0
locations_created = 0
models_mapped = 0
interventions_updated = 0
contracts_migrated = 0
# Run everything in a transaction block
with transaction.atomic():
for old_radar in its_radars:
# A. Map the location (TrafficLightIntersection)
intersection_code = old_radar.code.replace('RAD_PREV_', '').strip()
intersection, created = TrafficLightIntersection.objects.get_or_create(
code=intersection_code,
defaults={
'name_fr': f"Radar {intersection_code}",
'name_nl': f"Radar {intersection_code}",
'lon': old_radar.lon,
'lat': old_radar.lat,
'geom': old_radar.geom,
'geojson': old_radar.geojson,
'status': 'active',
'is_radar': True
}
)
if created:
locations_created += 1
elif not intersection.is_radar:
intersection.is_radar = True
intersection.save(update_fields=['is_radar'])
# B. Map the model (TrafficLightRadarModel)
its_model = old_radar.model
tl_model, created_model = TrafficLightRadarModel.objects.get_or_create(
code=its_model.code,
defaults={
'name_fr': its_model.name_fr,
'name_nl': its_model.name_nl,
'description': its_model.description,
'brand': its_model.brand,
'category': radar_category
}
)
if created_model:
models_mapped += 1
# C. Recreate/map the radar to TrafficLightRadar
new_radar = TrafficLightRadar.objects.create(
code=old_radar.code,
name_fr=old_radar.name_fr,
name_nl=old_radar.name_nl,
status=old_radar.status,
obsolescence=old_radar.obsolescence,
installation_date=old_radar.installation_date,
uninstallation_date=old_radar.uninstallation_date,
serial_number=old_radar.serial_number,
warranty_duration=old_radar.warranty_duration,
last_inspection_date=old_radar.last_inspection_date,
last_preventive_date=old_radar.last_preventive_date,
last_corrective_date=old_radar.last_corrective_date,
last_survey_date=old_radar.last_survey_date,
brand=old_radar.brand,
replaced_by=None,
marked_as_removed_date=old_radar.marked_as_removed_date,
marked_as_removed_by=old_radar.marked_as_removed_by,
note=old_radar.note,
validation_status=old_radar.validation_status,
updated_by=old_radar.updated_by,
lon=old_radar.lon,
lat=old_radar.lat,
geom=old_radar.geom,
geojson=old_radar.geojson,
model=tl_model,
intersection=intersection,
category=radar_category
)
transferred_count += 1
# D. Migrate associated Interventions
# Find all InterventionAssets referencing this old radar
int_assets = InterventionAsset.objects.filter(content_type=its_geo_asset_ct, object_id=old_radar.id)
for int_asset in int_assets:
# Update generic foreign key pointing to the new radar
int_asset.content_type = traffic_light_radar_ct
int_asset.object_id = new_radar.id
int_asset.save()
intervention = int_asset.intervention
# Update thematic of intervention
intervention.thematic = trafficlights_thematic
# Update asset category of intervention if it points to ITS Radars (ID 82)
if intervention.asset_category and intervention.asset_category.id == 82:
intervention.asset_category = radar_category
# Update location_code field if empty
if not intervention.location_code:
intervention.location_code = intersection.code
intervention.save()
# Create InterventionLocation pointing to the TrafficLightIntersection
InterventionLocation.objects.get_or_create(
intervention=intervention,
content_type=traffic_light_intersection_ct,
object_id=intersection.id
)
interventions_updated += 1
# E. Migrate associated Contracts
# For each ITSGeoAssetContract linked to this old radar
old_contracts = ITSGeoAssetContract.objects.filter(asset=old_radar)
for old_contract_link in old_contracts:
# Create corresponding TrafficLightContract for the intersection
TrafficLightContract.objects.get_or_create(
intersection=intersection,
contract=old_contract_link.contract,
defaults={
'status': old_contract_link.status,
'maintenance_type': 'other'
}
)
contracts_migrated += 1
# Clean up old contract link
old_contract_link.delete()
# F. Delete old ITSGeoAsset radar
old_radar.delete()
self.stdout.write(self.style.SUCCESS(
f"Successfully transferred {transferred_count}/{total_radars} prevention radars.\n"
f"Created {locations_created} TrafficLightIntersections.\n"
f"Mapped {models_mapped} TrafficLightRadarModels.\n"
f"Updated {interventions_updated} associated interventions/assets/locations.\n"
f"Migrated {contracts_migrated} contract links."
))