169 lines
No EOL
7.4 KiB
Python
169 lines
No EOL
7.4 KiB
Python
# ----------------------
|
|
# Control Centers Models
|
|
# ----------------------
|
|
|
|
from django.contrib.gis.db import models
|
|
from django.urls import reverse
|
|
from django.utils.translation import get_language
|
|
from django.core.exceptions import ValidationError
|
|
from django.utils.text import slugify
|
|
|
|
from assets.models import AbstractLocation, AbstractAsset, AbstractGeoAsset, AbstractAssetModel
|
|
from common.models import Document
|
|
from common.storages import PrivateMediaStorage
|
|
|
|
import os
|
|
|
|
private_storage = PrivateMediaStorage()
|
|
|
|
|
|
|
|
# Control Center Location
|
|
class ControlCenterLocation(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")
|
|
control_center = models.ForeignKey('ControlCenter', on_delete=models.SET_NULL, null=True, blank=True, related_name="all_locations")
|
|
|
|
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 clean(self):
|
|
if self.is_main_location and ControlCenterLocation.objects.filter(control_center=self.control_center, is_main_location=True).exclude(pk=self.pk).exists():
|
|
raise ValidationError("Ce centre de contrôle a déjà une localisation principale.")
|
|
|
|
def get_absolute_url(self):
|
|
return reverse(
|
|
'assets:controlcenters_locations_detail',
|
|
kwargs={
|
|
# 'asset_model': content_type.model,
|
|
'location_id': self.id
|
|
}
|
|
)
|
|
|
|
|
|
class ControlCenter(models.Model):
|
|
code = models.CharField(max_length=50, unique=True)
|
|
name_fr = models.CharField(max_length=200,null=True,blank=True)
|
|
name_nl = models.CharField(max_length=200,null=True,blank=True)
|
|
main_location = models.OneToOneField(ControlCenterLocation, on_delete=models.SET_NULL, null=True, blank=True, related_name="main_control_center")
|
|
description = models.TextField(null=True, blank=True)
|
|
|
|
def get_name(self):
|
|
lang = get_language()
|
|
name = getattr(self, f"name_{lang}", self.name_fr) or "" # Fallback to name_fr
|
|
return name
|
|
|
|
def get_active_assets(self):
|
|
return self.assets.filter(status='active')
|
|
|
|
def get_all_assets(self):
|
|
return self.assets.all()
|
|
|
|
def get_all_locations(self):
|
|
return self.all_locations.all()
|
|
|
|
def get_main_location(self):
|
|
return self.main_location
|
|
|
|
def __str__(self):
|
|
return self.code + " - " + self.get_name()
|
|
|
|
class Meta:
|
|
ordering = ["code"]
|
|
|
|
|
|
|
|
class ControlCenterAssetModel(AbstractAssetModel):
|
|
class Meta:
|
|
verbose_name = "Control Center Asset Model"
|
|
verbose_name_plural = "Control Center Asset Models"
|
|
|
|
class ControlCenterGeoAsset(AbstractGeoAsset):
|
|
model = models.ForeignKey(ControlCenterAssetModel, on_delete=models.PROTECT, null=True, blank=True, related_name="controlcenters_assets")
|
|
location = models.ForeignKey(ControlCenterLocation, related_name="assets", on_delete=models.SET_NULL, null=True, blank=True)
|
|
control_center = models.ForeignKey(ControlCenter, on_delete=models.SET_NULL, related_name="assets", null=True, blank=True)
|
|
|
|
class Meta:
|
|
indexes = [
|
|
models.Index(fields=["code"]),
|
|
]
|
|
|
|
def get_absolute_url(self):
|
|
return reverse('assets:controlcenters_assets_detail', kwargs={'asset_model': 'controlcentergeoasset', 'asset_id':self.id})
|
|
|
|
|
|
|
|
|
|
class ControlCenterContract(models.Model):
|
|
control_center = models.ForeignKey(ControlCenter, on_delete=models.CASCADE, related_name="controlcenters_contracts")
|
|
contract = models.ForeignKey("contracts.Contract", on_delete=models.CASCADE, related_name="controlcenters_contracts")
|
|
status = models.CharField(max_length=50, choices=[('active', 'Actif'), ('inactive', 'Inactif'), ('archived', 'Archivé')], default='active')
|
|
maintenance_type = models.CharField(max_length=50, choices=[('building', 'Bâtiment'), ('office', 'Bureautique'), ('system', 'Système'), ('other', 'Autre')], default='other')
|
|
|
|
def __str__(self):
|
|
return f"{self.control_center.code} - {self.contract.contract_number}"
|
|
|
|
class Meta:
|
|
verbose_name = "Control Center Contract"
|
|
verbose_name_plural = "Control Center Contracts"
|
|
unique_together = ('control_center', 'contract')
|
|
|
|
|
|
class ControlCenterGeoAssetContract(models.Model):
|
|
control_center_asset = models.ForeignKey(ControlCenterGeoAsset, on_delete=models.CASCADE, related_name="controlcenters_assets_contracts")
|
|
contract = models.ForeignKey("contracts.Contract", on_delete=models.CASCADE, related_name="controlcenters_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=[('building', 'Bâtiment'), ('office', 'Bureautique'), ('system', 'Système'), ('other', 'Autre')], default='other')
|
|
|
|
def __str__(self):
|
|
return f"{self.control_center_asset.code} - {self.contract.contract_number}"
|
|
|
|
class Meta:
|
|
verbose_name = "Control Center Asset Contract"
|
|
verbose_name_plural = "Control Center Asset Contracts"
|
|
unique_together = ('control_center_asset', 'contract')
|
|
|
|
|
|
|
|
|
|
def upload_to_controlcenter(instance, filename):
|
|
code = slugify(instance.control_center.code or "unknown") # Fallback si code est None
|
|
return os.path.join("assets_documents", "controlcenters", code, filename)
|
|
|
|
TU_DOCUMENT_TYPE_CHOICES = (
|
|
('other', 'Autre'),
|
|
)
|
|
|
|
# Control Center Location Document
|
|
class ControlCenterDocument(Document):
|
|
control_center = models.ForeignKey(ControlCenter, on_delete=models.CASCADE, related_name="documents", verbose_name="Associated Location")
|
|
file = models.FileField(upload_to=upload_to_controlcenter, storage=private_storage, verbose_name="Fichier", max_length=255)
|
|
thumbnail = models.ImageField(upload_to=upload_to_controlcenter, storage=private_storage, null=True, blank=True, max_length=255)
|
|
document_type = models.CharField(max_length=50, choices=TU_DOCUMENT_TYPE_CHOICES, default='other', verbose_name="Type de document")
|
|
|
|
|
|
# Control Center Asset Document
|
|
class ControlCenterAssetDocument(Document):
|
|
control_center_asset = models.ForeignKey(ControlCenterGeoAsset, on_delete=models.CASCADE, related_name="documents", verbose_name="Associated Location")
|
|
file = models.FileField(upload_to=upload_to_controlcenter, storage=private_storage, verbose_name="Fichier", max_length=255)
|
|
thumbnail = models.ImageField(upload_to=upload_to_controlcenter, storage=private_storage, null=True, blank=True, max_length=255)
|
|
document_type = models.CharField(max_length=50, choices=TU_DOCUMENT_TYPE_CHOICES, default='other', verbose_name="Type de document") |