loko/streetup/assets/models/its.py
2026-07-22 14:48:40 +02:00

132 lines
No EOL
5.3 KiB
Python

# ----------------------
# ITS Models
# ----------------------
from django.contrib.gis.db import models
from django.urls import reverse
from django.utils.text import slugify
from django.utils.translation import get_language
import os
from assets.models import AbstractLocation, AbstractAsset, AbstractGeoAsset, AbstractAssetModel
from common.models import Municipality, Document
from common.storages import PrivateMediaStorage
private_storage = PrivateMediaStorage()
# ITS locations
class ITSLocation(AbstractLocation):
geom = models.MultiPolygonField(srid=3812, null=True,blank=True)
parent_location = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name="child_locations")
is_main_location = models.BooleanField(default=False, verbose_name="Main Location")
def get_active_assets(self):
def collect_assets(location):
assets = list(location.assets.filter(status='active'))
for child in location.child_locations.all():
assets += collect_assets(child)
return assets
return collect_assets(self)
def get_all_assets(self):
def collect_assets(location):
assets = list(location.assets.all())
for child in location.child_locations.all():
assets += collect_assets(child)
return assets
return collect_assets(self)
def get_direct_child_assets(self):
return self.assets.all()
def get_absolute_url(self):
return reverse(
'assets:its_locations_detail',
kwargs={
'location_id': self.id
}
)
class Meta:
verbose_name = "ITS Location"
verbose_name_plural = "ITS Locations"
ordering = ["code"]
def upload_to_its_location(instance, filename):
location = instance.location
code = slugify(location.code or "unknown") # Fallback si code est None
return os.path.join("assets_documents", "its_locations", code, filename)
ITS_LOC_DOCUMENT_TYPE_CHOICES = (
('as_built', 'As Built'),
('schema', "Schéma"),
('other', 'Autre'),
)
# ITS Location Document
class ITSLocationDocument(Document):
location = models.ForeignKey(ITSLocation, on_delete=models.CASCADE, related_name="documents", verbose_name="Associated ITS Location")
file = models.FileField(upload_to=upload_to_its_location, storage=private_storage, verbose_name="Fichier", max_length=255)
thumbnail = models.ImageField(upload_to=upload_to_its_location, storage=private_storage, null=True, blank=True, max_length=255)
document_type = models.CharField(max_length=50, choices=ITS_LOC_DOCUMENT_TYPE_CHOICES, default='other', verbose_name="Type de document")
class ITSAssetModel(AbstractAssetModel):
class Meta:
verbose_name = "ITS Asset Model"
verbose_name_plural = "ITS Asset Models"
class ITSGeoAsset(AbstractGeoAsset):
model = models.ForeignKey(ITSAssetModel, on_delete=models.PROTECT)
location = models.ForeignKey(ITSLocation, related_name="assets", on_delete=models.SET_NULL, null=True, blank=True)
trafficlights_pole = models.ForeignKey("assets.TrafficLightPole", on_delete=models.SET_NULL, null=True, blank=True, related_name="its_assets", verbose_name="Traffic Light Pole")
lighting_pole = models.ForeignKey("assets.PublicLightingPole", on_delete=models.SET_NULL, null=True, blank=True, related_name="its_assets", verbose_name="Lighting Pole")
class Meta:
indexes = [
models.Index(fields=["code"]),
]
def get_absolute_url(self):
return reverse('assets:its_assets_detail', kwargs={'asset_model': 'itsgeoasset', 'asset_id':self.id})
class ITSLocationContract(models.Model):
location = models.ForeignKey(ITSLocation, on_delete=models.CASCADE, related_name="its_locations_contracts")
contract = models.ForeignKey("contracts.Contract", on_delete=models.CASCADE, related_name="its_locations_contracts")
status = models.CharField(max_length=50, choices=[('active', 'Actif'), ('inactive', 'Inactif'), ('archived', 'Archivé')], default='active')
maintenance_type = models.CharField(max_length=50, choices=[('equipments', 'Equipements'), ('office', 'Bureautique'), ('system', 'Système'), ('other', 'Autre')], default='other')
def __str__(self):
return f"{self.location.code} - {self.contract.contract_number}"
class Meta:
verbose_name = "ITS Location Contract"
verbose_name_plural = "ITS Location Contracts"
unique_together = ('location', 'contract')
class ITSGeoAssetContract(models.Model):
asset = models.ForeignKey(ITSGeoAsset, on_delete=models.CASCADE, related_name="its_assets_contracts")
contract = models.ForeignKey("contracts.Contract", on_delete=models.CASCADE, related_name="its_assets_contracts")
status = models.CharField(max_length=50, choices=[('active', 'Actif'), ('inactive', 'Inactif'), ('archived', 'Archivé')], default='active')
maintenance_type = models.CharField(max_length=50, choices=[('equipments', 'Equipements'), ('office', 'Bureautique'), ('system', 'Système'), ('other', 'Autre')], default='other')
def __str__(self):
return f"{self.asset.code} - {self.contract.contract_number}"
class Meta:
verbose_name = "ITS Asset Contract"
verbose_name_plural = "ITS Asset Contracts"
unique_together = ('asset', 'contract')