194 lines
8.8 KiB
Python
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."
|
|
))
|