feat: initialize project database migrations and core models structure
This commit is contained in:
parent
8c83ff764c
commit
b0f0341f4a
112 changed files with 823 additions and 3312 deletions
|
|
@ -1,11 +1,11 @@
|
|||
asgiref==3.11.0
|
||||
certifi==2025.11.12
|
||||
charset-normalizer==3.4.4
|
||||
crispy-bootstrap5==2025.6
|
||||
Django==5.2.8
|
||||
djangorestframework==3.16.1
|
||||
crispy-bootstrap5==2026.3
|
||||
Django==6.0.7
|
||||
djangorestframework==3.17.1
|
||||
djangorestframework-simplejwt==5.5.1
|
||||
django-crispy-forms==2.5
|
||||
django-crispy-forms==2.6
|
||||
et_xmlfile==2.0.0
|
||||
geopandas==1.1.1
|
||||
idna==3.11
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import assets.models.controlcenters
|
||||
import assets.models.its
|
||||
|
|
@ -26,7 +26,7 @@ class Migration(migrations.Migration):
|
|||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -78,7 +78,7 @@ class Migration(migrations.Migration):
|
|||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -183,7 +183,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -246,7 +246,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -490,7 +490,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -598,7 +598,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -702,7 +702,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -737,7 +737,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -764,7 +764,7 @@ class Migration(migrations.Migration):
|
|||
('buffer', models.FloatField(blank=True, null=True)),
|
||||
('width', models.FloatField(blank=True, null=True)),
|
||||
('length', models.FloatField(blank=True, null=True)),
|
||||
('bulb_types', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('tulipes', 'Tulipes'), ('jacynthes', 'Jacynthes'), ('jonquilles', 'Jonquilles'), ('narcisses', 'Narcisses'), ('crocus', 'Crocus'), ('perce_neige', 'Perce-neige'), ('autres', 'Autres')], max_length=50), blank=True, default=list, size=None, verbose_name='Types de bulbes')),
|
||||
('bulb_types', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('tulipes', 'Tulipes'), ('jacynthes', 'Jacynthes'), ('jonquilles', 'Jonquilles'), ('narcisses', 'Narcisses'), ('crocus', 'Crocus'), ('perce_neige', 'Perce-neige'), ('autres', 'Autres')], max_length=50), blank=True, default=list, verbose_name='Types de bulbes')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
|
|
@ -785,43 +785,6 @@ class Migration(migrations.Migration):
|
|||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureHollowGreenSpace',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=3812)),
|
||||
('surface_area', models.FloatField(blank=True, null=True)),
|
||||
('width', models.FloatField(blank=True, null=True)),
|
||||
('length', models.FloatField(blank=True, null=True)),
|
||||
('hgs_type', models.CharField(blank=True, choices=[('rain_garden', 'Jardin de pluie'), ('swale', 'Noue'), ('ditch', 'Fossé'), ('dry_basin', "Bassin sec/d'infiltration"), ('wet_basin', 'Bassin en eau')], max_length=50, null=True, verbose_name="Type d'EVC")),
|
||||
('coat_type', models.CharField(blank=True, choices=[('earth_stone_mixture', 'Mélange terre-pierre'), ('vegetal', 'Végétal'), ('grassed_structure', 'Structure enherbée'), ('non_aggregated_material', 'Matériau non agrégé'), ('mineral_filled_structure', 'Structure à remplissage minéral'), ('elevated_coating', 'Revêtement surélevé'), ('modular_porous', 'Modulaire poreux'), ('continuous_porous', 'Continu poreux'), ('impermeable', 'Impermeable')], max_length=50, null=True, verbose_name='Type de revêtement')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Espace vert creux',
|
||||
'verbose_name_plural': 'Espaces verts creux',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureLocation',
|
||||
fields=[
|
||||
|
|
@ -842,6 +805,72 @@ class Migration(migrations.Migration):
|
|||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureRWIAsset',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.GeometryField(blank=True, null=True, srid=3812)),
|
||||
('external_id', models.IntegerField(blank=True, null=True, verbose_name='External ID')),
|
||||
('code_name', models.CharField(blank=True, choices=[('AV', 'Stormwater inlet (Avaloir)'), ('BS', 'Sequenced border (Bordure séquencée)'), ('BI', "Injection port (Bouche d'injection)"), ('CA', 'Non-return valve (Clapet anti-retour)'), ('ES', 'Sedimentation (Empierrement sédimentation)'), ('KC', 'Kerb cell'), ('PI', "Infiltration well (Puits d'infiltration)"), ('SU', 'Overflow (Surverse)'), ('VI', "Isolation valve (Vanne d'isolation)"), ('VR', 'Control valve (Vanne de régulation)'), ('GT', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('FE', "Trickle of water (Filet d'eau)"), ('AR', 'Rail drain (Avaloir de rail)'), ('BA', 'Leveled edge (Bordure arasée)'), ('CI', 'Infiltration channel (Caniveau infiltrant)'), ('D', 'Drain'), ('TP', 'Overflowing (Trop plein)'), ('RES', 'Separate sewer system (Réseau égout séparatif)'), ('EVC', 'Hollow green space (Espace vert creux)'), ('OED', 'Decentralized underground structure (Ouvrage enterré décentralisé)'), ('OSI', 'Work on an impermeable surface (Ouvrage sur surface imperméable)'), ('TA', 'Alternative technique (Technique alternative)'), ('OA', 'Supplementary work (Ouvrage annexe)')], max_length=50, null=True, verbose_name='Code name')),
|
||||
('structure_type', models.CharField(blank=True, choices=[('avaloir', 'Stormwater inlet (Avaloir)'), ('bordure sequencee', 'Sequenced border (Bordure séquencée)'), ('bouche injection', "Injection port (Bouche d'injection)"), ('clapet anti-retour', 'Non-return valve (Clapet anti-retour)'), ('empierrement sedimentation', 'Sedimentation (Empierrement sédimentation)'), ('kerb cell', 'Kerb cell'), ('puits infiltration', "Infiltration well (Puits d'infiltration)"), ('surverse', 'Overflow (Surverse)'), ('vanne isolation', "Isolation valve (Vanne d'isolation)"), ('vanne regulation', 'Control valve (Vanne de régulation)'), ('gargouille de trottoir', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('filet eau', "Trickle of water (Filet d'eau)"), ('avaloir de rail', 'Rail drain (Avaloir de rail)'), ('bordure arasee', 'Leveled edge (Bordure arasée)'), ('caniveau infiltrant', 'Infiltration channel (Caniveau infiltrant)'), ('drain', 'Drain'), ('trop plein', 'Overflowing (Trop plein)'), ('reseau egout separatif', 'Separate sewer system (Réseau égout séparatif)'), ('bassin sec/infiltration', 'Dry/infiltration basin (Bassin sec/infiltration)'), ('bassin en eau', 'Wet basin (Bassin en eau)'), ('fosse', 'Ditch (Fossé)'), ('jardin de pluie', 'Rain garden (Jardin de pluie)'), ('noue', 'Swale (Noue)'), ('massif drainant', 'Draining structure (Massif drainant)'), ('tranchee drainante', 'Draining trench (Tranchée drainante)'), ('toiture stockante', 'Retention roof (Toiture stockante)'), ('toiture verte', 'Green roof (Toiture verte)'), ('bassin orage', "Stormwater basin (Bassin d'orage)"), ('SAUL-vide', 'SAUL-empty (SAUL-vide)'), ('SAUL-terre', 'SAUL-earth (SAUL-terre)'), ('citerne', 'Cistern (Citerne)'), ('espace vert sur dalle', 'Green space on slab (Espace vert sur dalle)'), ('bande filtrante', 'Filter strip (Bande filtrante)'), ('collecteur en beton poreux', 'Porous concrete collector (Collecteur en béton poreux)')], max_length=100, null=True, verbose_name='Structure type')),
|
||||
('geometry_type', models.CharField(blank=True, choices=[('point', 'Point'), ('line', 'Line'), ('polygon', 'Polygon')], max_length=50, null=True, verbose_name='Geometry type')),
|
||||
('project_manager', models.CharField(blank=True, choices=[('DPV', 'DPV'), ('DITP', 'DITP'), ('DEN', 'DEN'), ('DPO', 'DPO'), ('Beliris', 'Beliris'), ('Commune', 'Commune')], max_length=50, null=True, verbose_name='Project manager')),
|
||||
('construction_status', models.CharField(blank=True, choices=[('etude', 'Design (Étude)'), ('travaux', 'Construction (Travaux)'), ('reception provisoire', 'Provisional acceptance (Réception provisoire)'), ('reception definitive', 'Final acceptance (Réception définitive)')], max_length=100, null=True, verbose_name='Construction status')),
|
||||
('commissioning_date', models.DateField(blank=True, null=True, verbose_name='Commissioning date')),
|
||||
('condition', models.CharField(blank=True, choices=[('bon', 'Good (Bon)'), ('examen a programmer', 'Inspection to schedule (Examen à programmer)'), ('intervention curative necessaire', 'Curative action needed (Intervention curative nécessaire)'), ('refection totale necessaire', 'Total rehabilitation needed (Réfection totale nécessaire)'), ('travaux entretien a realiser', 'Maintenance works to perform (Travaux entretien à réaliser)'), ('travaux maintenance', 'Maintenance works (Travaux maintenance)'), ('travaux maintenance a programmer', 'Maintenance works to schedule (Travaux maintenance à programmer)')], max_length=100, null=True, verbose_name='Condition')),
|
||||
('administrator', models.CharField(blank=True, max_length=500, null=True, verbose_name='Administrator')),
|
||||
('monitoring', models.CharField(blank=True, max_length=500, null=True, verbose_name='Monitoring')),
|
||||
('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
|
||||
('has_filter', models.BooleanField(blank=True, null=True, verbose_name='Has filter')),
|
||||
('sewer_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Sewer connection')),
|
||||
('separate_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Separate network connection')),
|
||||
('hydro_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Hydro network connection')),
|
||||
('surface_area', models.FloatField(blank=True, null=True, verbose_name='Surface area (m²)')),
|
||||
('length', models.FloatField(blank=True, null=True, verbose_name='Length (m)')),
|
||||
('coating_category', models.CharField(blank=True, choices=[('Vegetal', 'Vegetal (Végétal)'), ('Structure enherbee', 'Grassed structure (Structure enherbée)'), ('Materiau non agrege', 'Unbound material (Matériau non agrégé)'), ('Structure a remplissage mineral', 'Mineral-filled structure (Structure à remplissage minéral)'), ('Revetement sureleve', 'Raised coating (Revêtement surélevé)'), ('Modulaire poreux', 'Porous modular (Modulaire poreux)'), ('Continu poreux', 'Porous continuous (Continu poreux)'), ('Impermeable', 'Impermeable (Imperméable)')], max_length=100, null=True, verbose_name='Coating category')),
|
||||
('coating_type', models.CharField(blank=True, choices=[('Pleine terre', 'Open soil (Pleine terre)'), ('Melange terre-pierre', 'Soil-stone mixture (Mélange terre-pierre)'), ('Paves a joints larges enherbes', 'Grassed wide-joint pavers (Pavés à joints larges enherbés)'), ('Dalles gazon en beton', 'Concrete grass grids (Dalles gazon en béton)'), ('Dalles alveolaires vegetalisees', 'Vegetated cellular tiles (Dalles alvéolaires végétalisées)'), ('Mulch vegetal', 'Woodchips/mulch (Mulch végétal)'), ('Graviers calcaires', 'Limestone gravel (Graviers calcaires)'), ('Graviers non calcaires', 'Non-limestone gravel (Graviers non calcaires)'), ('Terre battue', 'Dirt ground (Terre battue)'), ('Paves a joints larges engravillonnes', 'Gravel wide-joint pavers (Pavés à joints larges engravillonnés)'), ('Dalles alveolaires en gravier', 'Gravel cellular tiles (Dalles alvéolaires en gravier)'), ('Dalles en PEHD remplies de pave', 'HDPE tiles filled with pavers (Dalles en PEHD remplies de pavé)'), ('Grilles', 'Grates (Grilles)'), ('Platelages bois', 'Wooden decking (Platelages bois)'), ('Pave en beton poreux', 'Porous concrete pavers (Pavé en béton poreux)'), ('Dalle en beton poreux', 'Porous concrete slab (Dalle en béton poreux)'), ('Enrobes bitumineux poreux', 'Porous asphalt (Enrobés bitumineux poreux)'), ('Betons poreux', 'Porous concrete (Bétons poreux)'), ('Graviers lies a la resine', 'Resin-bound gravel (Graviers liés à la résine)'), ('Graviers concasses lies aux polymeres', 'Polymer-bound crushed gravel (Graviers concassés liés aux polymères)'), ('Revetements EPDM et ESBR', 'EPDM and SBR rubber coatings (Revêtements EPDM et ESBR)'), ('Revetements en beton de ciment non permeables', 'Non-porous cement concrete coatings (Revêtements en béton de ciment non perméables)'), ('Revetements bitumineux non permeables', 'Non-porous asphalt coatings (Revêtements bitumineux non perméables)'), ('Dallages non permeables', 'Non-porous tiling (Dallages non perméables)'), ('Pavages non permeables', 'Non-porous paving (Pavages non perméables)'), ('Autres revetements non permeables', 'Other non-porous coatings (Autres revêtements non perméables)')], max_length=100, null=True, verbose_name='Coating type')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'RWI Asset',
|
||||
'verbose_name_plural': 'RWI Assets',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureRWIAssetDocument',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description du document')),
|
||||
('upload_date', models.DateTimeField(auto_now=True, verbose_name='Date de téléversement')),
|
||||
('status', models.CharField(choices=[('active', 'Actif'), ('archived', 'Archivé')], default='active')),
|
||||
('file', models.FileField(max_length=255, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/rwi/', verbose_name='File')),
|
||||
('thumbnail', models.ImageField(blank=True, max_length=255, null=True, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/rwi/')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'RWI Asset Document',
|
||||
'verbose_name_plural': 'RWI Asset Documents',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureRWIZ',
|
||||
fields=[
|
||||
|
|
@ -867,7 +896,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -902,7 +931,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -936,7 +965,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -986,7 +1015,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1033,7 +1062,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1053,6 +1082,10 @@ class Migration(migrations.Migration):
|
|||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Public lighting pole',
|
||||
'verbose_name_plural': 'Public lighting poles',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PublicLightingPoleModel',
|
||||
|
|
@ -1112,7 +1145,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1133,7 +1166,7 @@ class Migration(migrations.Migration):
|
|||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('address', models.CharField(blank=True, max_length=2048, null=True)),
|
||||
('main_function', models.CharField(blank=True, choices=[('protection', 'Protection Asset'), ('antiterrorist', 'Antiterroriste'), ('parking_neutralization', 'Neutralisation stationnement'), ('road_safety', 'Sécurité routière'), ('public_space', 'Espace public'), ('construction', 'Chantier'), ('unidentified', 'Non identifié')], max_length=200, null=True)),
|
||||
('secondary_functions', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('protection', 'Protection Asset'), ('antiterrorist', 'Antiterroriste'), ('parking_neutralization', 'Neutralisation stationnement'), ('road_safety', 'Sécurité routière'), ('public_space', 'Espace public'), ('construction', 'Chantier'), ('unidentified', 'Non identifié')], max_length=200), blank=True, null=True, size=None)),
|
||||
('secondary_functions', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('protection', 'Protection Asset'), ('antiterrorist', 'Antiterroriste'), ('parking_neutralization', 'Neutralisation stationnement'), ('road_safety', 'Sécurité routière'), ('public_space', 'Espace public'), ('construction', 'Chantier'), ('unidentified', 'Non identifié')], max_length=200), blank=True, null=True)),
|
||||
('number_of_blocks', models.IntegerField(blank=True, null=True)),
|
||||
('length', models.FloatField(blank=True, null=True)),
|
||||
('recommended_action', models.CharField(blank=True, choices=[('keep', 'Maintenir'), ('remove', 'Enlever'), ('replace', 'Remplacer')], max_length=2048, null=True)),
|
||||
|
|
@ -1151,7 +1184,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1177,7 +1210,7 @@ class Migration(migrations.Migration):
|
|||
('nearby_vegetation', models.BooleanField(blank=True, null=True)),
|
||||
('possible_rooting', models.BooleanField(blank=True, null=True)),
|
||||
('is_defect', models.BooleanField(blank=True, null=True)),
|
||||
('defect_types', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('obstructed', 'Obstrué'), ('smell_cut_missing', 'Coupe-odeur manquant'), ('grate_broken', 'Grille cassée'), ('grate_missing', 'Grille manquante'), ('poor_water_flow', 'Mauvais écoulement'), ('other', 'Autre')], max_length=200), blank=True, null=True, size=None)),
|
||||
('defect_types', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('obstructed', 'Obstrué'), ('smell_cut_missing', 'Coupe-odeur manquant'), ('grate_broken', 'Grille cassée'), ('grate_missing', 'Grille manquante'), ('poor_water_flow', 'Mauvais écoulement'), ('other', 'Autre')], max_length=200), blank=True, null=True)),
|
||||
('defect_note', models.TextField(blank=True, null=True)),
|
||||
('related_image_type', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('altitude', models.FloatField(blank=True, null=True)),
|
||||
|
|
@ -1208,7 +1241,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1259,7 +1292,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1345,7 +1378,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1410,7 +1443,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1471,6 +1504,9 @@ class Migration(migrations.Migration):
|
|||
('name_nl', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('sgv_picture', models.ImageField(blank=True, null=True, upload_to='sign/signpanels_types/')),
|
||||
('default_width', models.FloatField(blank=True, null=True, verbose_name='Largeur par défaut (cm)')),
|
||||
('default_height', models.FloatField(blank=True, null=True, verbose_name='Hauteur par défaut (cm)')),
|
||||
('default_diameter', models.FloatField(blank=True, null=True, verbose_name='Diamètre par défaut (cm)')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
|
|
@ -1480,7 +1516,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1515,7 +1551,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1659,7 +1695,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1707,7 +1743,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1754,7 +1790,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1813,7 +1849,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1852,7 +1888,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1913,7 +1949,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -1934,7 +1970,7 @@ class Migration(migrations.Migration):
|
|||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Nom du détecteur')),
|
||||
('hardware', models.CharField(blank=True, max_length=255, null=True, verbose_name='Hardware')),
|
||||
('phases', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=50), blank=True, null=True, size=None, verbose_name='Phases associées')),
|
||||
('phases', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=50), blank=True, null=True, verbose_name='Phases associées')),
|
||||
('mentionned_on_plan', models.BooleanField(default=False, verbose_name='Mentionné sur le plan')),
|
||||
],
|
||||
options={
|
||||
|
|
@ -1963,7 +1999,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2011,7 +2047,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2087,6 +2123,7 @@ class Migration(migrations.Migration):
|
|||
('status', models.CharField(choices=[('active', 'Actif'), ('in_preparation', 'En préparation'), ('under_repair', 'En cours de réparation'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('inactive', 'Désactivé'), ('archived', 'Archivé')], default='active')),
|
||||
('begin_time', models.DateTimeField(blank=True, null=True)),
|
||||
('current_index', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('is_radar', models.BooleanField(default=False, verbose_name='Est un radar ?')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['code'],
|
||||
|
|
@ -2116,7 +2153,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2160,7 +2197,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2195,7 +2232,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2220,8 +2257,8 @@ class Migration(migrations.Migration):
|
|||
('ral', models.CharField(blank=True, max_length=200, null=True, verbose_name='RAL')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Poteau',
|
||||
'verbose_name_plural': 'Poteaux',
|
||||
'verbose_name': 'Traffic light pole',
|
||||
'verbose_name_plural': 'Traffic light poles',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
|
|
@ -2248,7 +2285,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -2273,6 +2310,101 @@ class Migration(migrations.Migration):
|
|||
'ordering': ['-commissioning_date'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadar',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Radar',
|
||||
'verbose_name_plural': 'Radars',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Traffic Light Radar Model',
|
||||
'verbose_name_plural': 'Traffic Light Radar Models',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarPole',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('colour', models.CharField(blank=True, max_length=200, null=True, verbose_name='Couleur')),
|
||||
('ral', models.CharField(blank=True, max_length=200, null=True, verbose_name='RAL')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Radar Pole',
|
||||
'verbose_name_plural': 'Radar Poles',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarPoleModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightVoltageHardware',
|
||||
fields=[
|
||||
|
|
@ -2280,7 +2412,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -79,6 +79,11 @@ class Migration(migrations.Migration):
|
|||
name='street',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fountains', to='assets.artworkstreet'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='assetcategory',
|
||||
name='allowed_models',
|
||||
field=models.ManyToManyField(blank=True, help_text="Les types de modèles d'assets (Django) autorisés pour cette catégorie.", related_name='asset_categories', to='contenttypes.contenttype', verbose_name='Modèles Django autorisés'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='assetcategory',
|
||||
name='parent',
|
||||
|
|
@ -489,26 +494,6 @@ class Migration(migrations.Migration):
|
|||
name='uploaded_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Ajouté par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='marked_as_removed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='replaced_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.naturehollowgreenspace', verbose_name='Remplacé par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='updated_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturelocation',
|
||||
name='category',
|
||||
|
|
@ -539,16 +524,46 @@ class Migration(migrations.Migration):
|
|||
name='location',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nature_benches', to='assets.naturelocation'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiasset',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiasset',
|
||||
name='marked_as_removed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiasset',
|
||||
name='replaced_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.naturerwiasset', verbose_name='Remplacé par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiasset',
|
||||
name='updated_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiassetdocument',
|
||||
name='managed_document',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_sources', to='documents.manageddocument'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiassetdocument',
|
||||
name='rwi_asset',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='assets.naturerwiasset', verbose_name='RWI Asset'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiassetdocument',
|
||||
name='uploaded_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Ajouté par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturerwiz',
|
||||
name='updated_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_location_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='location',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='hollow_green_spaces', to='assets.naturerwiz'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='natureshrub',
|
||||
name='category',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -11,7 +11,7 @@ class Migration(migrations.Migration):
|
|||
|
||||
dependencies = [
|
||||
('assets', '0003_initial'),
|
||||
('common', '0003_initial'),
|
||||
('common', '0004_initial'),
|
||||
('contracts', '0001_initial'),
|
||||
('documents', '0001_initial'),
|
||||
('observations', '0001_initial'),
|
||||
|
|
@ -889,6 +889,101 @@ class Migration(migrations.Migration):
|
|||
name='programming',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='documents', to='assets.trafficlightprogramming', verbose_name='Programmation associée'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='intersection',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='radars', to='assets.trafficlightintersection'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='marked_as_removed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='power_publiclighting_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='powered_radars', to='assets.publiclightingpole', verbose_name='Public Lighting Pole (Power)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='power_trafficlights_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='powered_radars', to='assets.trafficlightpole', verbose_name='Traffic Light Pole (Power)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='publiclighting_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.publiclightingpole', verbose_name='Public Lighting Pole (Support)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='replaced_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.trafficlightradar', verbose_name='Remplacé par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='trafficlights_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightpole', verbose_name='Traffic Light Pole (Support)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='updated_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarmodel',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='model',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='assets.trafficlightradarmodel'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='intersection',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='radar_poles', to='assets.trafficlightintersection'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='marked_as_removed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='replaced_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.trafficlightradarpole', verbose_name='Remplacé par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='updated_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightradarpole', verbose_name='Radar Pole (Support)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpolemodel',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='model',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.trafficlightradarpolemodel'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightvoltagehardware',
|
||||
name='category',
|
||||
|
|
|
|||
|
|
@ -1,188 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-23 05:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0004_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='artworkfountain',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='artworkmonument',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cleanglasscontainer',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cleanlitterbin',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='controlcentergeoasset',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='itsgeoasset',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='naturebench',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='naturegreensurface',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='naturehollowgreenspace',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='natureshrub',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='naturetree',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='publiclightingelectricalcabinet',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='publiclightinglightfixture',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='publiclightingpole',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roadconcreteblockset',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roaddrain',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roadfurniture',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roadsidewalk',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roadway',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signpanel',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signparkingspot',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signpole',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='structuregeoasset',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightaccessory',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightcable',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightcontroller',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightcontrollerhardware',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightdetector',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightelectricalcabinet',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightelectricalcabinetcontent',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightlantern',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightnetworkhardware',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightpole',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightprogramming',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightvoltagehardware',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-27 09:44
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0005_alter_artworkfountain_status_and_more'),
|
||||
('documents', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NatureGIEPAsset',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.GeometryField(blank=True, null=True, srid=3812)),
|
||||
('external_id', models.IntegerField(blank=True, null=True, verbose_name='External ID')),
|
||||
('code_name', models.CharField(blank=True, choices=[('AV', 'Stormwater inlet (Avaloir)'), ('BS', 'Sequenced border (Bordure séquencée)'), ('BI', "Injection port (Bouche d'injection)"), ('CA', 'Non-return valve (Clapet anti-retour)'), ('ES', 'Sedimentation (Empierrement sédimentation)'), ('KC', 'Kerb cell'), ('PI', "Infiltration well (Puits d'infiltration)"), ('SU', 'Overflow (Surverse)'), ('VI', "Isolation valve (Vanne d'isolation)"), ('VR', 'Control valve (Vanne de régulation)'), ('GT', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('FE', "Trickle of water (Filet d'eau)"), ('AR', 'Rail drain (Avaloir de rail)'), ('BA', 'Leveled edge (Bordure arasée)'), ('CI', 'Infiltration channel (Caniveau infiltrant)'), ('D', 'Drain'), ('TP', 'Overflowing (Trop plein)'), ('RES', 'Separate sewer system (Réseau égout séparatif)'), ('EVC', 'Hollow green space (Espace vert creux)'), ('OED', 'Decentralized underground structure (Ouvrage enterré décentralisé)'), ('OSI', 'Work on an impermeable surface (Ouvrage sur surface imperméable)'), ('TA', 'Alternative technique (Technique alternative)'), ('OA', 'Supplementary work (Ouvrage annexe)')], max_length=50, null=True, verbose_name='Code name')),
|
||||
('structure_type', models.CharField(blank=True, choices=[('avaloir', 'Stormwater inlet (Avaloir)'), ('bordure sequencee', 'Sequenced border (Bordure séquencée)'), ('bouche injection', "Injection port (Bouche d'injection)"), ('clapet anti-retour', 'Non-return valve (Clapet anti-retour)'), ('empierrement sedimentation', 'Sedimentation (Empierrement sédimentation)'), ('kerb cell', 'Kerb cell'), ('puits infiltration', "Infiltration well (Puits d'infiltration)"), ('surverse', 'Overflow (Surverse)'), ('vanne isolation', "Isolation valve (Vanne d'isolation)"), ('vanne regulation', 'Control valve (Vanne de régulation)'), ('gargouille de trottoir', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('filet eau', "Trickle of water (Filet d'eau)"), ('avaloir de rail', 'Rail drain (Avaloir de rail)'), ('bordure arasee', 'Leveled edge (Bordure arasée)'), ('caniveau infiltrant', 'Infiltration channel (Caniveau infiltrant)'), ('drain', 'Drain'), ('trop plein', 'Overflowing (Trop plein)'), ('reseau egout separatif', 'Separate sewer system (Réseau égout séparatif)'), ('bassin sec/infiltration', 'Dry/infiltration basin (Bassin sec/infiltration)'), ('bassin en eau', 'Wet basin (Bassin en eau)'), ('fosse', 'Ditch (Fossé)'), ('jardin de pluie', 'Rain garden (Jardin de pluie)'), ('noue', 'Swale (Noue)'), ('massif drainant', 'Draining structure (Massif drainant)'), ('tranchee drainante', 'Draining trench (Tranchée drainante)'), ('toiture stockante', 'Retention roof (Toiture stockante)'), ('toiture verte', 'Green roof (Toiture verte)'), ('bassin orage', "Stormwater basin (Bassin d'orage)"), ('SAUL-vide', 'SAUL-empty (SAUL-vide)'), ('SAUL-terre', 'SAUL-earth (SAUL-terre)'), ('citerne', 'Cistern (Citerne)'), ('espace vert sur dalle', 'Green space on slab (Espace vert sur dalle)'), ('bande filtrante', 'Filter strip (Bande filtrante)'), ('collecteur en beton poreux', 'Porous concrete collector (Collecteur en béton poreux)')], max_length=100, null=True, verbose_name='Structure type')),
|
||||
('project_manager', models.CharField(blank=True, choices=[('DPV', 'DPV'), ('DITP', 'DITP'), ('DEN', 'DEN'), ('DPO', 'DPO'), ('Beliris', 'Beliris'), ('Commune', 'Commune')], max_length=50, null=True, verbose_name='Project manager')),
|
||||
('location_precision', models.CharField(blank=True, choices=[('precise', 'Precise (Précise)'), ('supposee', 'Assumed (Supposée)')], max_length=50, null=True, verbose_name='Location precision')),
|
||||
('construction_status', models.CharField(blank=True, choices=[('etude', 'Design (Étude)'), ('travaux', 'Construction (Travaux)'), ('reception provisoire', 'Provisional acceptance (Réception provisoire)'), ('reception definitive', 'Final acceptance (Réception définitive)')], max_length=100, null=True, verbose_name='Construction status')),
|
||||
('commissioning_date', models.DateField(blank=True, null=True, verbose_name='Commissioning date')),
|
||||
('condition', models.CharField(blank=True, choices=[('bon', 'Good (Bon)'), ('examen a programmer', 'Inspection to schedule (Examen à programmer)'), ('intervention curative necessaire', 'Curative action needed (Intervention curative nécessaire)'), ('refection totale necessaire', 'Total rehabilitation needed (Réfection totale nécessaire)'), ('travaux entretien a realiser', 'Maintenance works to perform (Travaux entretien à réaliser)'), ('travaux maintenance', 'Maintenance works (Travaux maintenance)'), ('travaux maintenance a programmer', 'Maintenance works to schedule (Travaux maintenance à programmer)')], max_length=100, null=True, verbose_name='Condition')),
|
||||
('administrator', models.CharField(blank=True, max_length=500, null=True, verbose_name='Administrator')),
|
||||
('monitoring', models.CharField(blank=True, max_length=500, null=True, verbose_name='Monitoring')),
|
||||
('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
|
||||
('has_filter', models.BooleanField(blank=True, null=True, verbose_name='Has filter')),
|
||||
('sewer_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Sewer connection')),
|
||||
('separate_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Separate network connection')),
|
||||
('hydro_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Hydro network connection')),
|
||||
('surface_area', models.FloatField(blank=True, null=True, verbose_name='Surface area (m²)')),
|
||||
('length', models.FloatField(blank=True, null=True, verbose_name='Length (m)')),
|
||||
('coating_category', models.CharField(blank=True, choices=[('Vegetal', 'Vegetal (Végétal)'), ('Structure enherbee', 'Grassed structure (Structure enherbée)'), ('Materiau non agrege', 'Unbound material (Matériau non agrégé)'), ('Structure a remplissage mineral', 'Mineral-filled structure (Structure à remplissage minéral)'), ('Revetement sureleve', 'Raised coating (Revêtement surélevé)'), ('Modulaire poreux', 'Porous modular (Modulaire poreux)'), ('Continu poreux', 'Porous continuous (Continu poreux)'), ('Impermeable', 'Impermeable (Imperméable)')], max_length=100, null=True, verbose_name='Coating category')),
|
||||
('coating_type', models.CharField(blank=True, choices=[('Pleine terre', 'Open soil (Pleine terre)'), ('Melange terre-pierre', 'Soil-stone mixture (Mélange terre-pierre)'), ('Paves a joints larges enherbes', 'Grassed wide-joint pavers (Pavés à joints larges enherbés)'), ('Dalles gazon en beton', 'Concrete grass grids (Dalles gazon en béton)'), ('Dalles alveolaires vegetalisees', 'Vegetated cellular tiles (Dalles alvéolaires végétalisées)'), ('Mulch vegetal', 'Woodchips/mulch (Mulch végétal)'), ('Graviers calcaires', 'Limestone gravel (Graviers calcaires)'), ('Graviers non calcaires', 'Non-limestone gravel (Graviers non calcaires)'), ('Terre battue', 'Dirt ground (Terre battue)'), ('Paves a joints larges engravillonnes', 'Gravel wide-joint pavers (Pavés à joints larges engravillonnés)'), ('Dalles alveolaires en gravier', 'Gravel cellular tiles (Dalles alvéolaires en gravier)'), ('Dalles en PEHD remplies de pave', 'HDPE tiles filled with pavers (Dalles en PEHD remplies de pavé)'), ('Grilles', 'Grates (Grilles)'), ('Platelages bois', 'Wooden decking (Platelages bois)'), ('Pave en beton poreux', 'Porous concrete pavers (Pavé en béton poreux)'), ('Dalle en beton poreux', 'Porous concrete slab (Dalle en béton poreux)'), ('Enrobes bitumineux poreux', 'Porous asphalt (Enrobés bitumineux poreux)'), ('Betons poreux', 'Porous concrete (Bétons poreux)'), ('Graviers lies a la resine', 'Resin-bound gravel (Graviers liés à la résine)'), ('Graviers concasses lies aux polymeres', 'Polymer-bound crushed gravel (Graviers concassés liés aux polymères)'), ('Revetements EPDM et ESBR', 'EPDM and SBR rubber coatings (Revêtements EPDM et ESBR)'), ('Revetements en beton de ciment non permeables', 'Non-porous cement concrete coatings (Revêtements en béton de ciment non perméables)'), ('Revetements bitumineux non permeables', 'Non-porous asphalt coatings (Revêtements bitumineux non perméables)'), ('Dallages non permeables', 'Non-porous tiling (Dallages non perméables)'), ('Pavages non permeables', 'Non-porous paving (Pavages non perméables)'), ('Autres revetements non permeables', 'Other non-porous coatings (Autres revêtements non perméables)')], max_length=100, null=True, verbose_name='Coating type')),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.naturegiepasset', verbose_name='Remplacé par')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'GIEP Asset',
|
||||
'verbose_name_plural': 'GIEP Assets',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureGIEPAssetDocument',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description du document')),
|
||||
('upload_date', models.DateTimeField(auto_now=True, verbose_name='Date de téléversement')),
|
||||
('status', models.CharField(choices=[('active', 'Actif'), ('archived', 'Archivé')], default='active')),
|
||||
('file', models.FileField(max_length=255, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/giep/', verbose_name='File')),
|
||||
('thumbnail', models.ImageField(blank=True, max_length=255, null=True, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/giep/')),
|
||||
('giep_asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='assets.naturegiepasset', verbose_name='GIEP Asset')),
|
||||
('managed_document', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_sources', to='documents.manageddocument')),
|
||||
('uploaded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Ajouté par')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'GIEP Asset Document',
|
||||
'verbose_name_plural': 'GIEP Asset Documents',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-27 09:50
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0006_naturegiepasset_naturegiepassetdocument'),
|
||||
('documents', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='naturegiepassetdocument',
|
||||
name='giep_asset',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='naturegiepassetdocument',
|
||||
name='managed_document',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='naturegiepassetdocument',
|
||||
name='uploaded_by',
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureRWIAsset',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.GeometryField(blank=True, null=True, srid=3812)),
|
||||
('external_id', models.IntegerField(blank=True, null=True, verbose_name='External ID')),
|
||||
('code_name', models.CharField(blank=True, choices=[('AV', 'Stormwater inlet (Avaloir)'), ('BS', 'Sequenced border (Bordure séquencée)'), ('BI', "Injection port (Bouche d'injection)"), ('CA', 'Non-return valve (Clapet anti-retour)'), ('ES', 'Sedimentation (Empierrement sédimentation)'), ('KC', 'Kerb cell'), ('PI', "Infiltration well (Puits d'infiltration)"), ('SU', 'Overflow (Surverse)'), ('VI', "Isolation valve (Vanne d'isolation)"), ('VR', 'Control valve (Vanne de régulation)'), ('GT', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('FE', "Trickle of water (Filet d'eau)"), ('AR', 'Rail drain (Avaloir de rail)'), ('BA', 'Leveled edge (Bordure arasée)'), ('CI', 'Infiltration channel (Caniveau infiltrant)'), ('D', 'Drain'), ('TP', 'Overflowing (Trop plein)'), ('RES', 'Separate sewer system (Réseau égout séparatif)'), ('EVC', 'Hollow green space (Espace vert creux)'), ('OED', 'Decentralized underground structure (Ouvrage enterré décentralisé)'), ('OSI', 'Work on an impermeable surface (Ouvrage sur surface imperméable)'), ('TA', 'Alternative technique (Technique alternative)'), ('OA', 'Supplementary work (Ouvrage annexe)')], max_length=50, null=True, verbose_name='Code name')),
|
||||
('structure_type', models.CharField(blank=True, choices=[('avaloir', 'Stormwater inlet (Avaloir)'), ('bordure sequencee', 'Sequenced border (Bordure séquencée)'), ('bouche injection', "Injection port (Bouche d'injection)"), ('clapet anti-retour', 'Non-return valve (Clapet anti-retour)'), ('empierrement sedimentation', 'Sedimentation (Empierrement sédimentation)'), ('kerb cell', 'Kerb cell'), ('puits infiltration', "Infiltration well (Puits d'infiltration)"), ('surverse', 'Overflow (Surverse)'), ('vanne isolation', "Isolation valve (Vanne d'isolation)"), ('vanne regulation', 'Control valve (Vanne de régulation)'), ('gargouille de trottoir', 'Sidewalk gargoyle (Gargouille de trottoir)'), ('filet eau', "Trickle of water (Filet d'eau)"), ('avaloir de rail', 'Rail drain (Avaloir de rail)'), ('bordure arasee', 'Leveled edge (Bordure arasée)'), ('caniveau infiltrant', 'Infiltration channel (Caniveau infiltrant)'), ('drain', 'Drain'), ('trop plein', 'Overflowing (Trop plein)'), ('reseau egout separatif', 'Separate sewer system (Réseau égout séparatif)'), ('bassin sec/infiltration', 'Dry/infiltration basin (Bassin sec/infiltration)'), ('bassin en eau', 'Wet basin (Bassin en eau)'), ('fosse', 'Ditch (Fossé)'), ('jardin de pluie', 'Rain garden (Jardin de pluie)'), ('noue', 'Swale (Noue)'), ('massif drainant', 'Draining structure (Massif drainant)'), ('tranchee drainante', 'Draining trench (Tranchée drainante)'), ('toiture stockante', 'Retention roof (Toiture stockante)'), ('toiture verte', 'Green roof (Toiture verte)'), ('bassin orage', "Stormwater basin (Bassin d'orage)"), ('SAUL-vide', 'SAUL-empty (SAUL-vide)'), ('SAUL-terre', 'SAUL-earth (SAUL-terre)'), ('citerne', 'Cistern (Citerne)'), ('espace vert sur dalle', 'Green space on slab (Espace vert sur dalle)'), ('bande filtrante', 'Filter strip (Bande filtrante)'), ('collecteur en beton poreux', 'Porous concrete collector (Collecteur en béton poreux)')], max_length=100, null=True, verbose_name='Structure type')),
|
||||
('geometry_type', models.CharField(blank=True, choices=[('point', 'Point'), ('line', 'Line'), ('polygon', 'Polygon')], max_length=50, null=True, verbose_name='Geometry type')),
|
||||
('project_manager', models.CharField(blank=True, choices=[('DPV', 'DPV'), ('DITP', 'DITP'), ('DEN', 'DEN'), ('DPO', 'DPO'), ('Beliris', 'Beliris'), ('Commune', 'Commune')], max_length=50, null=True, verbose_name='Project manager')),
|
||||
('location_precision', models.CharField(blank=True, choices=[('precise', 'Precise (Précise)'), ('supposee', 'Assumed (Supposée)')], max_length=50, null=True, verbose_name='Location precision')),
|
||||
('construction_status', models.CharField(blank=True, choices=[('etude', 'Design (Étude)'), ('travaux', 'Construction (Travaux)'), ('reception provisoire', 'Provisional acceptance (Réception provisoire)'), ('reception definitive', 'Final acceptance (Réception définitive)')], max_length=100, null=True, verbose_name='Construction status')),
|
||||
('commissioning_date', models.DateField(blank=True, null=True, verbose_name='Commissioning date')),
|
||||
('condition', models.CharField(blank=True, choices=[('bon', 'Good (Bon)'), ('examen a programmer', 'Inspection to schedule (Examen à programmer)'), ('intervention curative necessaire', 'Curative action needed (Intervention curative nécessaire)'), ('refection totale necessaire', 'Total rehabilitation needed (Réfection totale nécessaire)'), ('travaux entretien a realiser', 'Maintenance works to perform (Travaux entretien à réaliser)'), ('travaux maintenance', 'Maintenance works (Travaux maintenance)'), ('travaux maintenance a programmer', 'Maintenance works to schedule (Travaux maintenance à programmer)')], max_length=100, null=True, verbose_name='Condition')),
|
||||
('administrator', models.CharField(blank=True, max_length=500, null=True, verbose_name='Administrator')),
|
||||
('monitoring', models.CharField(blank=True, max_length=500, null=True, verbose_name='Monitoring')),
|
||||
('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
|
||||
('has_filter', models.BooleanField(blank=True, null=True, verbose_name='Has filter')),
|
||||
('sewer_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Sewer connection')),
|
||||
('separate_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Separate network connection')),
|
||||
('hydro_network_connection', models.CharField(blank=True, choices=[('connecte', 'Connected (Connecté)'), ('non connecte', 'Not connected (Non connecté)')], max_length=50, null=True, verbose_name='Hydro network connection')),
|
||||
('surface_area', models.FloatField(blank=True, null=True, verbose_name='Surface area (m²)')),
|
||||
('length', models.FloatField(blank=True, null=True, verbose_name='Length (m)')),
|
||||
('coating_category', models.CharField(blank=True, choices=[('Vegetal', 'Vegetal (Végétal)'), ('Structure enherbee', 'Grassed structure (Structure enherbée)'), ('Materiau non agrege', 'Unbound material (Matériau non agrégé)'), ('Structure a remplissage mineral', 'Mineral-filled structure (Structure à remplissage minéral)'), ('Revetement sureleve', 'Raised coating (Revêtement surélevé)'), ('Modulaire poreux', 'Porous modular (Modulaire poreux)'), ('Continu poreux', 'Porous continuous (Continu poreux)'), ('Impermeable', 'Impermeable (Imperméable)')], max_length=100, null=True, verbose_name='Coating category')),
|
||||
('coating_type', models.CharField(blank=True, choices=[('Pleine terre', 'Open soil (Pleine terre)'), ('Melange terre-pierre', 'Soil-stone mixture (Mélange terre-pierre)'), ('Paves a joints larges enherbes', 'Grassed wide-joint pavers (Pavés à joints larges enherbés)'), ('Dalles gazon en beton', 'Concrete grass grids (Dalles gazon en béton)'), ('Dalles alveolaires vegetalisees', 'Vegetated cellular tiles (Dalles alvéolaires végétalisées)'), ('Mulch vegetal', 'Woodchips/mulch (Mulch végétal)'), ('Graviers calcaires', 'Limestone gravel (Graviers calcaires)'), ('Graviers non calcaires', 'Non-limestone gravel (Graviers non calcaires)'), ('Terre battue', 'Dirt ground (Terre battue)'), ('Paves a joints larges engravillonnes', 'Gravel wide-joint pavers (Pavés à joints larges engravillonnés)'), ('Dalles alveolaires en gravier', 'Gravel cellular tiles (Dalles alvéolaires en gravier)'), ('Dalles en PEHD remplies de pave', 'HDPE tiles filled with pavers (Dalles en PEHD remplies de pavé)'), ('Grilles', 'Grates (Grilles)'), ('Platelages bois', 'Wooden decking (Platelages bois)'), ('Pave en beton poreux', 'Porous concrete pavers (Pavé en béton poreux)'), ('Dalle en beton poreux', 'Porous concrete slab (Dalle en béton poreux)'), ('Enrobes bitumineux poreux', 'Porous asphalt (Enrobés bitumineux poreux)'), ('Betons poreux', 'Porous concrete (Bétons poreux)'), ('Graviers lies a la resine', 'Resin-bound gravel (Graviers liés à la résine)'), ('Graviers concasses lies aux polymeres', 'Polymer-bound crushed gravel (Graviers concassés liés aux polymères)'), ('Revetements EPDM et ESBR', 'EPDM and SBR rubber coatings (Revêtements EPDM et ESBR)'), ('Revetements en beton de ciment non permeables', 'Non-porous cement concrete coatings (Revêtements en béton de ciment non perméables)'), ('Revetements bitumineux non permeables', 'Non-porous asphalt coatings (Revêtements bitumineux non perméables)'), ('Dallages non permeables', 'Non-porous tiling (Dallages non perméables)'), ('Pavages non permeables', 'Non-porous paving (Pavages non perméables)'), ('Autres revetements non permeables', 'Other non-porous coatings (Autres revêtements non perméables)')], max_length=100, null=True, verbose_name='Coating type')),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.naturerwiasset', verbose_name='Remplacé par')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'RWI Asset',
|
||||
'verbose_name_plural': 'RWI Assets',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NatureRWIAssetDocument',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(blank=True, null=True, verbose_name='Description du document')),
|
||||
('upload_date', models.DateTimeField(auto_now=True, verbose_name='Date de téléversement')),
|
||||
('status', models.CharField(choices=[('active', 'Actif'), ('archived', 'Archivé')], default='active')),
|
||||
('file', models.FileField(max_length=255, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/rwi/', verbose_name='File')),
|
||||
('thumbnail', models.ImageField(blank=True, max_length=255, null=True, storage=common.storages.PrivateMediaStorage(), upload_to='assets_documents/nature/rwi/')),
|
||||
('managed_document', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_sources', to='documents.manageddocument')),
|
||||
('rwi_asset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='assets.naturerwiasset', verbose_name='RWI Asset')),
|
||||
('uploaded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Ajouté par')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'RWI Asset Document',
|
||||
'verbose_name_plural': 'RWI Asset Documents',
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='NatureGIEPAsset',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='NatureGIEPAssetDocument',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-27 12:12
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0007_remove_naturegiepassetdocument_giep_asset_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='NatureHollowGreenSpace',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-30 13:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0008_delete_naturehollowgreenspace'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='signpaneltype',
|
||||
name='default_diameter',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='Diamètre par défaut (cm)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signpaneltype',
|
||||
name='default_height',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='Hauteur par défaut (cm)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signpaneltype',
|
||||
name='default_width',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='Largeur par défaut (cm)'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-22 08:31
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0009_signpaneltype_default_diameter_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Traffic Light Radar Model',
|
||||
'verbose_name_plural': 'Traffic Light Radar Models',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadar',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
('intersection', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='radars', to='assets.trafficlightintersection')),
|
||||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.trafficlightradar', verbose_name='Remplacé par')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
('model', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='assets.trafficlightradarmodel')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Radar',
|
||||
'verbose_name_plural': 'Radars',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
from django.db import migrations
|
||||
|
||||
def create_radar_preventif_category(apps, schema_editor):
|
||||
Thematic = apps.get_model('common', 'Thematic')
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
|
||||
# Get trafficlights thematic
|
||||
try:
|
||||
tl_thematic = Thematic.objects.get(code='trafficlights')
|
||||
except Thematic.DoesNotExist:
|
||||
tl_thematic = Thematic.objects.create(
|
||||
code='trafficlights',
|
||||
name_fr='Feux de signalisation',
|
||||
name_nl='Verkeerslichten'
|
||||
)
|
||||
|
||||
# Get or create radar_preventif category
|
||||
category, created = AssetCategory.objects.get_or_create(
|
||||
code='TL_RADAR_PREVENTIF',
|
||||
defaults={
|
||||
'name_fr': 'Radar Préventif',
|
||||
'name_nl': 'Preventieve radar',
|
||||
'thematic': tl_thematic
|
||||
}
|
||||
)
|
||||
if not created and category.thematic != tl_thematic:
|
||||
category.thematic = tl_thematic
|
||||
category.save()
|
||||
|
||||
def reverse_radar_preventif_category(apps, schema_editor):
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
AssetCategory.objects.filter(code='TL_RADAR_PREVENTIF').delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0010_trafficlightradarmodel_trafficlightradar'),
|
||||
('common', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_radar_preventif_category, reverse_radar_preventif_category),
|
||||
]
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-22 12:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def populate_is_radar(apps, schema_editor):
|
||||
TrafficLightIntersection = apps.get_model('assets', 'TrafficLightIntersection')
|
||||
TrafficLightRadar = apps.get_model('assets', 'TrafficLightRadar')
|
||||
|
||||
# Intersections linked to at least one radar are radar intersections
|
||||
radar_intersection_ids = TrafficLightRadar.objects.filter(intersection__isnull=False).values_list('intersection_id', flat=True).distinct()
|
||||
TrafficLightIntersection.objects.filter(id__in=radar_intersection_ids).update(is_radar=True)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0011_create_radar_preventif_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trafficlightintersection',
|
||||
name='is_radar',
|
||||
field=models.BooleanField(default=False, verbose_name='Est un radar ?'),
|
||||
),
|
||||
migrations.RunPython(populate_is_radar, migrations.RunPython.noop),
|
||||
]
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
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),
|
||||
]
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-25 12:13
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0013_update_rwi_assets_codification'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='naturerwiasset',
|
||||
name='location_precision',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-26 12:23
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0014_remove_nature_rwi_asset_location_precision'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.publiclightingpole'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-26 12:41
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0015_trafficlightradar_pole'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='publiclighting_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.publiclightingpole'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='trafficlights_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightpole'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarPole',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('serial_number', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('warranty_duration', models.IntegerField(blank=True, null=True, verbose_name='Duration of the warranty (months)')),
|
||||
('last_inspection_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_preventive_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_corrective_date', models.DateTimeField(blank=True, null=True)),
|
||||
('last_survey_date', models.DateTimeField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('marked_as_removed_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de marquage comme retiré')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='Note')),
|
||||
('validation_status', models.CharField(blank=True, choices=[('to_be_validated', 'À valider'), ('validated', 'Validé'), ('to_be_completed', 'À compléter'), ('rejected', 'Rejeté')], max_length=50, null=True, verbose_name='Statut de validation')),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('lon', models.FloatField(blank=True, null=True)),
|
||||
('lat', models.FloatField(blank=True, null=True)),
|
||||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('geojson', models.TextField(blank=True, null=True)),
|
||||
('colour', models.CharField(blank=True, max_length=200, null=True, verbose_name='Couleur')),
|
||||
('ral', models.CharField(blank=True, max_length=200, null=True, verbose_name='RAL')),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
('intersection', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='radar_poles', to='assets.trafficlightintersection')),
|
||||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='assets.trafficlightradarpole', verbose_name='Remplacé par')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Radar Pole',
|
||||
'verbose_name_plural': 'Radar Poles',
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightradar',
|
||||
name='pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightradarpole'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrafficLightRadarPoleModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('brand', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='model',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='assets.trafficlightradarpolemodel'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
from django.db import migrations
|
||||
|
||||
def create_radar_pole_category(apps, schema_editor):
|
||||
Thematic = apps.get_model('common', 'Thematic')
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
|
||||
# Get trafficlights thematic
|
||||
try:
|
||||
tl_thematic = Thematic.objects.get(code='trafficlights')
|
||||
except Thematic.DoesNotExist:
|
||||
tl_thematic = Thematic.objects.create(
|
||||
code='trafficlights',
|
||||
name_fr='Feux de signalisation',
|
||||
name_nl='Verkeerslichten'
|
||||
)
|
||||
|
||||
# Get or create radar_pole category
|
||||
category, created = AssetCategory.objects.get_or_create(
|
||||
code='TL_RADAR_POLE',
|
||||
defaults={
|
||||
'name_fr': 'Poteau radar',
|
||||
'name_nl': 'Radarpaal',
|
||||
'thematic': tl_thematic
|
||||
}
|
||||
)
|
||||
if not created and category.thematic != tl_thematic:
|
||||
category.thematic = tl_thematic
|
||||
category.save()
|
||||
|
||||
def reverse_radar_pole_category(apps, schema_editor):
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
AssetCategory.objects.filter(code='TL_RADAR_POLE').delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0016_trafficlightradar_publiclighting_pole_and_more'),
|
||||
('common', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_radar_pole_category, reverse_radar_pole_category),
|
||||
]
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-26 16:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0017_create_radar_pole_category'),
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='publiclightingpole',
|
||||
options={'verbose_name': 'Public lighting pole', 'verbose_name_plural': 'Public lighting poles'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='trafficlightpole',
|
||||
options={'verbose_name': 'Traffic light pole', 'verbose_name_plural': 'Traffic light poles'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='assetcategory',
|
||||
name='allowed_models',
|
||||
field=models.ManyToManyField(blank=True, help_text="Les types de modèles d'assets (Django) autorisés pour cette catégorie.", related_name='asset_categories', to='contenttypes.contenttype', verbose_name='Modèles Django autorisés'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
from django.db import migrations
|
||||
|
||||
def populate_allowed_models(apps, schema_editor):
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
|
||||
# Mapping of category codes to Django model name strings (lowercase)
|
||||
mapping = {
|
||||
# Traffic lights
|
||||
'TL_POTEAU': ['trafficlightpole'],
|
||||
'TL_CABLE': ['trafficlightcable'],
|
||||
'TL_LANTERNE': ['trafficlightlantern'],
|
||||
'TL_REGELAAR': ['trafficlightcontroller'],
|
||||
'TL_ARMOIRE': ['trafficlightelectricalcabinet'],
|
||||
'TL_DETEC_BP': ['trafficlightdetector'],
|
||||
'TL_DETEC_RADAR': ['trafficlightdetector'],
|
||||
'TL_DETEC_VIDEO': ['trafficlightdetector'],
|
||||
'TL_DETEC_OTHER': ['trafficlightdetector'],
|
||||
'TL_BORNIER': ['trafficlightaccessory'],
|
||||
'TL_DIVERS': ['trafficlightaccessory'],
|
||||
'TL_RADAR_PREVENTIF': ['trafficlightradar'],
|
||||
'TL_RADAR_POLE': ['trafficlightradarpole'],
|
||||
|
||||
# Public lighting
|
||||
'LI_poles': ['publiclightingpole'],
|
||||
'LI_lightfixtures': ['publiclightinglightfixture'],
|
||||
'LI_electrical_cabinets': ['publiclightingelectricalcabinet'],
|
||||
|
||||
# Cleanliness
|
||||
'CL_BASKET': ['cleanlitterbin'],
|
||||
'CL_BUBBLE': ['cleanglasscontainer'],
|
||||
|
||||
# Nature
|
||||
'NAT_GREEN_AREAS': ['naturegreensurface'],
|
||||
'NAT_TREES': ['naturetree'],
|
||||
'NAT_RWI': ['naturerwiasset'],
|
||||
'NAT_FURNITURES': ['naturebench', 'natureshrub'],
|
||||
|
||||
# Artworks
|
||||
'ART_MONUMENT': ['artworkmonument'],
|
||||
'ART_FONTAIN': ['artworkfountain'],
|
||||
}
|
||||
|
||||
for category_code, model_names in mapping.items():
|
||||
try:
|
||||
category = AssetCategory.objects.get(code=category_code)
|
||||
for model_name in model_names:
|
||||
try:
|
||||
ct = ContentType.objects.get(app_label='assets', model=model_name)
|
||||
category.allowed_models.add(ct)
|
||||
except ContentType.DoesNotExist:
|
||||
print(f"ContentType assets.{model_name} not found.")
|
||||
except AssetCategory.DoesNotExist:
|
||||
pass
|
||||
|
||||
def clear_allowed_models(apps, schema_editor):
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
for category in AssetCategory.objects.all():
|
||||
category.allowed_models.clear()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0018_alter_publiclightingpole_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(populate_allowed_models, clear_allowed_models),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-27 07:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0019_populate_assetcategory_allowed_models'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightradarpole',
|
||||
name='model',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.trafficlightradarpolemodel'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-03 09:16
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def set_default_validation_status(apps, schema_editor):
|
||||
model_names = [
|
||||
'trafficlightpole', 'trafficlightcable', 'trafficlightlantern', 'trafficlightcontroller',
|
||||
'trafficlightcontrollerhardware', 'trafficlightdetector', 'trafficlightnetworkhardware',
|
||||
'trafficlightvoltagehardware', 'trafficlightelectricalcabinet', 'trafficlightelectricalcabinetcontent',
|
||||
'trafficlightaccessory', 'trafficlightprogramming', 'trafficlightradarpole', 'trafficlightradar',
|
||||
'publiclightingpole', 'publiclightinglightfixture', 'publiclightingelectricalcabinet', 'artworkmonument',
|
||||
'artworkfountain', 'naturegreensurface', 'naturetree', 'natureshrub', 'naturebench',
|
||||
'naturerwiasset', 'structuregeoasset', 'controlcentergeoasset', 'signpole', 'signpanel',
|
||||
'signparkingspot', 'roadway', 'roadsidewalk', 'roadfurniture', 'roadconcreteblockset',
|
||||
'roaddrain', 'itsgeoasset', 'cleanlitterbin', 'cleanglasscontainer'
|
||||
]
|
||||
for model_name in model_names:
|
||||
try:
|
||||
Model = apps.get_model('assets', model_name)
|
||||
# Update all active assets with no validation status to 'validated'
|
||||
Model.objects.filter(status='active', validation_status__isnull=True).update(validation_status='validated')
|
||||
Model.objects.filter(status='active', validation_status='').update(validation_status='validated')
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
def reverse_default_validation_status(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0020_alter_trafficlightradarpole_model'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(set_default_validation_status, reverse_default_validation_status),
|
||||
]
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
# Generated by hand
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
def sync_trafficlights_documents(apps, schema_editor):
|
||||
from assets.models import TrafficLightIntersection as ActiveIntersection, TrafficLightIntersectionDocument as ActiveIntersectionDoc
|
||||
from assets.views.trafficlights import ensure_intersection_document_folder, generate_dxf_overlay_managed_document
|
||||
from documents.models import ensure_document_for_legacy
|
||||
|
||||
for intersection in ActiveIntersection.objects.all():
|
||||
try:
|
||||
ensure_intersection_document_folder(intersection)
|
||||
except Exception as e:
|
||||
print(f"Error ensuring document folder for intersection {intersection.id}: {e}")
|
||||
|
||||
for doc in ActiveIntersectionDoc.objects.all():
|
||||
try:
|
||||
import os
|
||||
if not doc.file or not doc.file.name:
|
||||
continue
|
||||
|
||||
# If the file does not exist on disk, we skip it gracefully
|
||||
if not os.path.exists(doc.file.path):
|
||||
print(f"Migration: File not found on disk, skipping sync for {doc.file.name}")
|
||||
continue
|
||||
|
||||
# Sync it to the ManagedDocument system
|
||||
ensure_document_for_legacy(doc)
|
||||
|
||||
# If it's a DXF, generate the overlay
|
||||
if doc.file.name.lower().endswith('.dxf') and doc.managed_document:
|
||||
generate_dxf_overlay_managed_document(doc.managed_document, user=doc.uploaded_by)
|
||||
except Exception as e:
|
||||
print(f"Error syncing document during migration for {doc.file.name if doc.file else 'None'}: {e}")
|
||||
|
||||
def reverse_sync_trafficlights_documents(apps, schema_editor):
|
||||
pass
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0021_set_default_validation_status_for_active'),
|
||||
('documents', '0003_manageddocument_georeference_coords_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(sync_trafficlights_documents, reverse_sync_trafficlights_documents),
|
||||
]
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-10 09:13
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0022_sync_trafficlights_documents'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='power_publiclighting_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='powered_radars', to='assets.publiclightingpole', verbose_name='Public Lighting Pole (Power)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trafficlightradar',
|
||||
name='power_trafficlights_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='powered_radars', to='assets.trafficlightpole', verbose_name='Traffic Light Pole (Power)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightradar',
|
||||
name='pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightradarpole', verbose_name='Radar Pole (Support)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightradar',
|
||||
name='publiclighting_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.publiclightingpole', verbose_name='Public Lighting Pole (Support)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trafficlightradar',
|
||||
name='trafficlights_pole',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='radars', to='assets.trafficlightpole', verbose_name='Traffic Light Pole (Support)'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import authorizations.models
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
from django.db import migrations
|
||||
|
||||
def create_authorizations_view(apps, schema_editor):
|
||||
AppView = apps.get_model('common', 'AppView')
|
||||
AppView.objects.get_or_create(
|
||||
code='authorizations',
|
||||
defaults={
|
||||
'name_fr': 'Autorisations',
|
||||
'name_nl': 'Autorisaties',
|
||||
'icon': 'bi-file-earmark-text',
|
||||
'url_name': 'authorizations:authorization_list',
|
||||
'is_default': False,
|
||||
'order': 40,
|
||||
}
|
||||
)
|
||||
|
||||
def remove_authorizations_view(apps, schema_editor):
|
||||
AppView = apps.get_model('common', 'AppView')
|
||||
AppView.objects.filter(code='authorizations').delete()
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('authorizations', '0001_initial'),
|
||||
('common', '0011_userwarehouselocationaccess_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_authorizations_view, remove_authorizations_view),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
import django.contrib.postgres.fields
|
||||
|
|
@ -113,6 +113,7 @@ class Migration(migrations.Migration):
|
|||
('can_process_observations', models.BooleanField(default=False, verbose_name='Peut traiter les observations')),
|
||||
('can_view_projects', models.BooleanField(default=False, verbose_name='Peut voir les projets')),
|
||||
('can_edit_projects', models.BooleanField(default=False, verbose_name='Peut éditer les projets')),
|
||||
('can_validate_assets', models.BooleanField(default=False, verbose_name='Peut valider les assets')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Thématique utilisateur',
|
||||
|
|
@ -150,6 +151,18 @@ class Migration(migrations.Migration):
|
|||
'verbose_name_plural': 'Accès Entrepôts',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserWarehouseLocationAccess',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('can_perform_inventory', models.BooleanField(default=False, verbose_name="Peut faire l'inventaire")),
|
||||
('can_validate_inventory', models.BooleanField(default=False, verbose_name="Peut valider l'inventaire")),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Accès Emplacement',
|
||||
'verbose_name_plural': 'Accès Emplacements',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AssetTypePermissionConfig',
|
||||
fields=[
|
||||
|
|
@ -275,8 +288,8 @@ class Migration(migrations.Migration):
|
|||
('can_view', models.BooleanField(default=False, verbose_name='Peut visualiser')),
|
||||
('can_edit', models.BooleanField(default=False, verbose_name='Peut modifier')),
|
||||
('can_delete', models.BooleanField(default=False, verbose_name='Peut supprimer')),
|
||||
('editable_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs que cet utilisateur peut modifier sur cet objet. Si renseignée (non vide), remplace complètement les champs autorisés par le rôle.', null=True, size=None, verbose_name='Champs modifiables')),
|
||||
('visible_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs que cet utilisateur peut voir sur cet objet. Si renseignée (non vide), remplace complètement les champs affichés par défaut.', null=True, size=None, verbose_name='Champs visibles')),
|
||||
('editable_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs que cet utilisateur peut modifier sur cet objet. Si renseignée (non vide), remplace complètement les champs autorisés par le rôle.', null=True, verbose_name='Champs modifiables')),
|
||||
('visible_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs que cet utilisateur peut voir sur cet objet. Si renseignée (non vide), remplace complètement les champs affichés par défaut.', null=True, verbose_name='Champs visibles')),
|
||||
('content_type', models.ForeignKey(help_text="Le modèle Django de l'asset ou de la location concernée.", on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name="Type d'objet")),
|
||||
],
|
||||
options={
|
||||
|
|
@ -291,8 +304,8 @@ class Migration(migrations.Migration):
|
|||
('can_view', models.BooleanField(default=False, verbose_name='Peut visualiser')),
|
||||
('can_edit', models.BooleanField(default=False, verbose_name='Peut modifier')),
|
||||
('can_delete', models.BooleanField(default=False, verbose_name='Peut supprimer')),
|
||||
('editable_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs modifiables pour tous les objets de ce type. Si renseignée (non vide), remplace les champs autorisés par le rôle. Peut être écrasée objet par objet via UserAssetAccess.', null=True, size=None, verbose_name='Champs modifiables')),
|
||||
('visible_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs visibles pour tous les objets de ce type. Si renseignée (non vide), remplace les champs affichés par défaut. Peut être écrasée objet par objet via UserAssetAccess.', null=True, size=None, verbose_name='Champs visibles')),
|
||||
('editable_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs modifiables pour tous les objets de ce type. Si renseignée (non vide), remplace les champs autorisés par le rôle. Peut être écrasée objet par objet via UserAssetAccess.', null=True, verbose_name='Champs modifiables')),
|
||||
('visible_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, help_text='Liste des noms de champs visibles pour tous les objets de ce type. Si renseignée (non vide), remplace les champs affichés par défaut. Peut être écrasée objet par objet via UserAssetAccess.', null=True, verbose_name='Champs visibles')),
|
||||
('content_type', models.ForeignKey(help_text="Le modèle Django concerné (s'applique à toutes ses instances).", on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name="Type d'asset")),
|
||||
],
|
||||
options={
|
||||
|
|
@ -312,14 +325,23 @@ class Migration(migrations.Migration):
|
|||
('hide_intervention_map_by_default', models.BooleanField(default=False, help_text="Affiche un bouton permettant d'afficher la carte au besoin.", verbose_name='Masquer la carte des interventions par défaut')),
|
||||
('intervention_list_layout', models.CharField(choices=[('both', 'Tableau et carte'), ('table_only', 'Tableau seul'), ('map_only', 'Carte seule')], default='both', help_text='Préférence de disposition pour la vue liste des interventions.', max_length=20, verbose_name='Disposition de la liste des interventions')),
|
||||
('intervention_list_filters', models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue liste des interventions.', verbose_name='Filtres de la liste des interventions')),
|
||||
('mobile_intervention_list_filters', models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue mobile de la liste des interventions.', verbose_name='Filtres de la liste des interventions mobile')),
|
||||
('intervention_list_sort', models.JSONField(blank=True, default=dict, help_text='Préférences de tri pour la vue liste des interventions.', verbose_name='Tri de la liste des interventions')),
|
||||
('intervention_list_columns', models.JSONField(blank=True, default=None, help_text='Liste des champs masqués dans le tableau de la vue liste des interventions.', null=True, verbose_name='Colonnes masquées de la liste des interventions')),
|
||||
('observation_list_filters', models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue liste des observations.', verbose_name='Filtres de la liste des observations')),
|
||||
('observation_list_sort', models.JSONField(blank=True, default=dict, help_text='Préférences de tri pour la vue liste des observations.', verbose_name='Tri de la liste des observations')),
|
||||
('project_list_filters', models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue liste des projets.', verbose_name='Filtres de la liste des projets')),
|
||||
('project_list_sort', models.JSONField(blank=True, default=dict, help_text='Préférences de tri pour la vue liste des projets.', verbose_name='Tri de la liste des projets')),
|
||||
('assets_list_layout', models.CharField(choices=[('both', 'Tableau et carte'), ('table_only', 'Tableau seul'), ('map_only', 'Carte seule')], default='both', help_text='Préférence de disposition pour la vue liste des assets.', max_length=20, verbose_name='Disposition de la liste des assets')),
|
||||
('auto_logout_hours', models.PositiveIntegerField(blank=True, help_text="Nombre d'heures après la connexion avant déconnexion automatique. Laisser vide pour désactiver.", null=True, verbose_name='Déconnexion automatique (heures)')),
|
||||
('panoramax_can_upload', models.BooleanField(default=False, help_text="Permet à l'utilisateur d'uploader de nouvelles photos ou vidéos 360 pour Panoramax.", verbose_name='Peut uploader des photos 360')),
|
||||
('can_add_unique_tag_documents', models.BooleanField(default=False, help_text="Permet aux utilisateurs externes d'ajouter/modifier des documents avec des tags uniques (CME, PIS, As-Built, etc.).", verbose_name='Peut ajouter des documents avec tags uniques')),
|
||||
('esign_can_edit', models.BooleanField(default=False, help_text='Permission pour éditer les panneaux et les poteaux.', verbose_name='eSign : Peut éditer')),
|
||||
('esign_can_manage_rcp', models.BooleanField(default=False, help_text='Permission pour créer, modifier et supprimer les RCP.', verbose_name='eSign : Peut gérer les RCP')),
|
||||
('esign_can_validate_rcp', models.BooleanField(default=False, help_text='Permission pour valider les RCP.', verbose_name='eSign : Peut valider les RCP')),
|
||||
('reporting_preferences', models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour les différentes pages du reporting.', verbose_name='Préférences du reporting')),
|
||||
('assets_index_preferences', models.JSONField(blank=True, default=dict, help_text='Préférences de la page assets (thématiques actives, catégories, filtres, position carte).', verbose_name='Préférences de la page index unifiée')),
|
||||
('calendar_preferences', models.JSONField(blank=True, default=dict, help_text="Préférences de la page calendrier (mode d'affichage, zoom, filtres actifs, état d'expansion du backlog).", null=True, verbose_name='Préférences du calendrier')),
|
||||
('accessible_views', models.ManyToManyField(blank=True, help_text="Les vues/applications auxquelles l'utilisateur a accès.", related_name='user_configs', to='common.appview', verbose_name='Vues accessibles')),
|
||||
('approval_categories', models.ManyToManyField(blank=True, help_text="Catégories d'assets pour lesquelles l'utilisateur approuve des interventions. Si vide, aucun filtre de catégorie n'est appliqué.", related_name='approver_user_configs', to='assets.assetcategory', verbose_name="Catégories d'approbation")),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -12,7 +11,6 @@ class Migration(migrations.Migration):
|
|||
dependencies = [
|
||||
('common', '0001_initial'),
|
||||
('contracts', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
|
@ -26,88 +24,4 @@ class Migration(migrations.Migration):
|
|||
name='default_thematic',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_user_accesses', to='common.thematic'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='linked_configs',
|
||||
field=models.ManyToManyField(blank=True, to='common.userconfig', verbose_name='Comptes liés'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='roles',
|
||||
field=models.ManyToManyField(blank=True, to='common.role'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='config', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userassettypeaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='asset_type_accesses', to='common.userconfig', verbose_name='Configuration utilisateur'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userassetaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='asset_accesses', to='common.userconfig', verbose_name='Configuration utilisateur'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserApprovalConfig',
|
||||
fields=[
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Configuration approbateur',
|
||||
'verbose_name_plural': 'Configurations approbateurs',
|
||||
'ordering': ['user__username'],
|
||||
'proxy': True,
|
||||
'indexes': [],
|
||||
'constraints': [],
|
||||
},
|
||||
bases=('common.userconfig',),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usercontractaccess',
|
||||
name='contract',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contracts.contract'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usercontractaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.userconfig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='contracts',
|
||||
field=models.ManyToManyField(related_name='user_accesses', through='common.UserContractAccess', to='contracts.contract'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usercontractstatuspermission',
|
||||
name='user_contract',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_permissions', to='common.usercontractaccess'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userthematics',
|
||||
name='thematic',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.thematic'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userthematics',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userthematics', to='common.userconfig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='thematics',
|
||||
field=models.ManyToManyField(related_name='user_accesses', through='common.UserThematics', to='common.thematic'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userthematicstatuspermission',
|
||||
name='user_thematic',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_permissions', to='common.userthematics'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userwarehouseaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userwarehouses', to='common.userconfig'),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -10,74 +11,99 @@ class Migration(migrations.Migration):
|
|||
|
||||
dependencies = [
|
||||
('common', '0002_initial'),
|
||||
('stock', '0001_initial'),
|
||||
('contracts', '0001_initial'),
|
||||
('sign', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userwarehouseaccess',
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.warehouse'),
|
||||
model_name='userconfig',
|
||||
name='esign_organizations',
|
||||
field=models.ManyToManyField(blank=True, help_text="Les gestionnaires (communes, Bruxelles Mobilité) pour lesquels l'utilisateur a des permissions.", related_name='user_configs', to='sign.organization', verbose_name='eSign : Gestionnaires'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='warehouses',
|
||||
field=models.ManyToManyField(blank=True, related_name='user_accesses', through='common.UserWarehouseAccess', to='stock.warehouse'),
|
||||
name='linked_configs',
|
||||
field=models.ManyToManyField(blank=True, to='common.userconfig', verbose_name='Comptes liés'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['level'], name='common_requ_level_55ef16_idx'),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='roles',
|
||||
field=models.ManyToManyField(blank=True, to='common.role'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['user'], name='common_requ_user_id_3781cb_idx'),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='config', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['status_code'], name='common_requ_status__b046e1_idx'),
|
||||
migrations.AddField(
|
||||
model_name='userassettypeaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='asset_type_accesses', to='common.userconfig', verbose_name='Configuration utilisateur'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['timestamp', 'level'], name='common_requ_timesta_264745_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userassettypeaccess',
|
||||
unique_together={('user_config', 'content_type')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
migrations.AddField(
|
||||
model_name='userassetaccess',
|
||||
index=models.Index(fields=['content_type', 'object_id'], name='common_user_content_e5ef8d_idx'),
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='asset_accesses', to='common.userconfig', verbose_name='Configuration utilisateur'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userassetaccess',
|
||||
unique_together={('user_config', 'content_type', 'object_id')},
|
||||
migrations.CreateModel(
|
||||
name='UserApprovalConfig',
|
||||
fields=[
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Configuration approbateur',
|
||||
'verbose_name_plural': 'Configurations approbateurs',
|
||||
'ordering': ['user__username'],
|
||||
'proxy': True,
|
||||
'indexes': [],
|
||||
'constraints': [],
|
||||
},
|
||||
bases=('common.userconfig',),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usercontractaccess',
|
||||
unique_together={('user_config', 'contract')},
|
||||
migrations.AddField(
|
||||
model_name='usercontractaccess',
|
||||
name='contract',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contracts.contract'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
migrations.AddField(
|
||||
model_name='usercontractaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.userconfig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='contracts',
|
||||
field=models.ManyToManyField(related_name='user_accesses', through='common.UserContractAccess', to='contracts.contract'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='usercontractstatuspermission',
|
||||
index=models.Index(fields=['user_contract', 'status', 'can_view'], name='ucsp_status_canview_idx'),
|
||||
name='user_contract',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_permissions', to='common.usercontractaccess'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usercontractstatuspermission',
|
||||
unique_together={('user_contract', 'status')},
|
||||
migrations.AddField(
|
||||
model_name='userthematics',
|
||||
name='thematic',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.thematic'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userthematics',
|
||||
unique_together={('user_config', 'thematic')},
|
||||
migrations.AddField(
|
||||
model_name='userthematics',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userthematics', to='common.userconfig'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='thematics',
|
||||
field=models.ManyToManyField(related_name='user_accesses', through='common.UserThematics', to='common.thematic'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userthematicstatuspermission',
|
||||
index=models.Index(fields=['user_thematic', 'status', 'can_view'], name='utsp_status_canview_idx'),
|
||||
name='user_thematic',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status_permissions', to='common.userthematics'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userthematicstatuspermission',
|
||||
unique_together={('user_thematic', 'status')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userwarehouseaccess',
|
||||
unique_together={('user_config', 'warehouse')},
|
||||
migrations.AddField(
|
||||
model_name='userwarehouseaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userwarehouses', to='common.userconfig'),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
102
streetup/common/migrations/0004_initial.py
Normal file
102
streetup/common/migrations/0004_initial.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
('stock', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userwarehouseaccess',
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.warehouse'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='warehouses',
|
||||
field=models.ManyToManyField(blank=True, related_name='user_accesses', through='common.UserWarehouseAccess', to='stock.warehouse'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userwarehouselocationaccess',
|
||||
name='user_config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userlocations', to='common.userconfig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userwarehouselocationaccess',
|
||||
name='warehouse_location',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_accesses', to='stock.warehouselocation', verbose_name='Emplacement'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='warehouse_locations',
|
||||
field=models.ManyToManyField(blank=True, related_name='user_configs', through='common.UserWarehouseLocationAccess', to='stock.warehouselocation'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['level'], name='common_requ_level_55ef16_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['user'], name='common_requ_user_id_3781cb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['status_code'], name='common_requ_status__b046e1_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='requestlog',
|
||||
index=models.Index(fields=['timestamp', 'level'], name='common_requ_timesta_264745_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userassettypeaccess',
|
||||
unique_together={('user_config', 'content_type')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='userassetaccess',
|
||||
index=models.Index(fields=['content_type', 'object_id'], name='common_user_content_e5ef8d_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userassetaccess',
|
||||
unique_together={('user_config', 'content_type', 'object_id')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usercontractaccess',
|
||||
unique_together={('user_config', 'contract')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='usercontractstatuspermission',
|
||||
index=models.Index(fields=['user_contract', 'status', 'can_view'], name='ucsp_status_canview_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usercontractstatuspermission',
|
||||
unique_together={('user_contract', 'status')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userthematics',
|
||||
unique_together={('user_config', 'thematic')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='userthematicstatuspermission',
|
||||
index=models.Index(fields=['user_thematic', 'status', 'can_view'], name='utsp_status_canview_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userthematicstatuspermission',
|
||||
unique_together={('user_thematic', 'status')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userwarehouseaccess',
|
||||
unique_together={('user_config', 'warehouse')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='userwarehouselocationaccess',
|
||||
unique_together={('user_config', 'warehouse_location')},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-23 05:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='assets_index_preferences',
|
||||
field=models.JSONField(blank=True, default=dict, help_text='Préférences de la page assets (thématiques actives, catégories, filtres, position carte).', verbose_name='Préférences de la page index unifiée'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-24 09:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0004_userconfig_assets_index_preferences'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='calendar_preferences',
|
||||
field=models.JSONField(blank=True, default=dict, help_text="Préférences de la page calendrier (mode d'affichage, zoom, filtres actifs, état d'expansion du backlog).", null=True, verbose_name='Préférences du calendrier'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-30 08:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0005_userconfig_calendar_preferences'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='esign_can_edit',
|
||||
field=models.BooleanField(default=False, help_text='Permission pour éditer les panneaux et les poteaux.', verbose_name='eSign : Peut éditer'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='esign_can_manage_rcp',
|
||||
field=models.BooleanField(default=False, help_text='Permission pour créer, modifier et supprimer les RCP.', verbose_name='eSign : Peut gérer les RCP'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='esign_can_validate_rcp',
|
||||
field=models.BooleanField(default=False, help_text='Permission pour valider les RCP.', verbose_name='eSign : Peut valider les RCP'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-30 10:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0006_userconfig_esign_can_edit_and_more'),
|
||||
('sign', '0003_alter_signpanel_street_alter_signpole_street'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='esign_organizations',
|
||||
field=models.ManyToManyField(blank=True, help_text="Les gestionnaires (communes, Bruxelles Mobilité) pour lesquels l'utilisateur a des permissions.", related_name='user_configs', to='sign.organization', verbose_name='eSign : Gestionnaires'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
# Generated by Django on 2026-06-10
|
||||
|
||||
from django.db import migrations
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.conf import settings
|
||||
import zipfile
|
||||
import xml.etree.ElementTree as ET
|
||||
import unicodedata
|
||||
import random
|
||||
import string
|
||||
import os
|
||||
|
||||
def normalize_text(text):
|
||||
nfkd_form = unicodedata.normalize('NFKD', text)
|
||||
only_ascii = "".join([c for c in nfkd_form if not unicodedata.combining(c)])
|
||||
cleaned = "".join([c.lower() for c in only_ascii if c.isalnum()])
|
||||
return cleaned
|
||||
|
||||
def generate_password():
|
||||
first_char = random.choice(string.ascii_uppercase)
|
||||
rest_chars = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(11))
|
||||
return first_char + rest_chars
|
||||
|
||||
def create_agents_regie(apps, schema_editor):
|
||||
User = apps.get_model('auth', 'User')
|
||||
Role = apps.get_model('common', 'Role')
|
||||
UserConfig = apps.get_model('common', 'UserConfig')
|
||||
Company = apps.get_model('contracts', 'Company')
|
||||
CompanyMember = apps.get_model('contracts', 'CompanyMember')
|
||||
|
||||
# Find the ODS file path
|
||||
ods_path = os.path.join(settings.BASE_DIR, '..', 'external_files', 'agents_regie.ods')
|
||||
if not os.path.exists(ods_path):
|
||||
ods_path = os.path.join(settings.BASE_DIR, 'external_files', 'agents_regie.ods')
|
||||
|
||||
if not os.path.exists(ods_path):
|
||||
print(f"\n[WARNING] agents_regie.ods not found at {ods_path}. Skipping user creation.")
|
||||
return
|
||||
|
||||
# Parse ODS file
|
||||
namespaces = {
|
||||
'table': 'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
|
||||
'text': 'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
|
||||
'office': 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'
|
||||
}
|
||||
|
||||
agents = []
|
||||
with zipfile.ZipFile(ods_path, 'r') as z:
|
||||
content_xml = z.read('content.xml')
|
||||
root = ET.fromstring(content_xml)
|
||||
tables = root.findall('.//table:table', namespaces)
|
||||
for table in tables:
|
||||
rows = table.findall('.//table:table-row', namespaces)
|
||||
for idx, row in enumerate(rows):
|
||||
cells = []
|
||||
for cell in row.findall('.//table:table-cell', namespaces):
|
||||
repeated = cell.get('{' + namespaces['table'] + '}number-columns-repeated')
|
||||
rep_count = int(repeated) if repeated else 1
|
||||
text_elems = cell.findall('.//text:p', namespaces)
|
||||
cell_text = "".join([t.text if t.text else "" for t in text_elems])
|
||||
for _ in range(rep_count):
|
||||
cells.append(cell_text)
|
||||
|
||||
if any(cells):
|
||||
while cells and cells[-1] == "":
|
||||
cells.pop()
|
||||
if idx == 0:
|
||||
continue
|
||||
if len(cells) >= 2:
|
||||
name = cells[0].strip()
|
||||
firstname = cells[1].strip()
|
||||
if name and firstname:
|
||||
agents.append((name, firstname))
|
||||
|
||||
if not agents:
|
||||
print("\n[WARNING] No agents found in agents_regie.ods. Skipping.")
|
||||
return
|
||||
|
||||
role_tech, _ = Role.objects.get_or_create(name='technician')
|
||||
company_regie, _ = Company.objects.get_or_create(name='BM - Régie')
|
||||
|
||||
created_users = []
|
||||
passwords_file_lines = [
|
||||
"=== BM - Régie : Nouveaux Techniciens ===",
|
||||
f"Généré le : {os.getenv('CURRENT_TIME', '2026-06-10')}",
|
||||
"-" * 50
|
||||
]
|
||||
|
||||
for name, firstname in agents:
|
||||
last_name_formatted = name.capitalize()
|
||||
first_name_formatted = firstname
|
||||
|
||||
first_letter = normalize_text(first_name_formatted)[:1]
|
||||
last_name_normalized = normalize_text(last_name_formatted)
|
||||
username = f"{first_letter}{last_name_normalized}"
|
||||
|
||||
if User.objects.filter(username=username).exists():
|
||||
continue
|
||||
|
||||
password = generate_password()
|
||||
|
||||
# Create user
|
||||
user = User.objects.create(
|
||||
username=username,
|
||||
first_name=first_name_formatted,
|
||||
last_name=last_name_formatted,
|
||||
password=make_password(password)
|
||||
)
|
||||
|
||||
# Create UserConfig
|
||||
config = UserConfig.objects.create(
|
||||
user=user,
|
||||
company=company_regie
|
||||
)
|
||||
config.roles.add(role_tech)
|
||||
|
||||
# Create CompanyMember
|
||||
CompanyMember.objects.create(
|
||||
user=user,
|
||||
name=first_name_formatted
|
||||
)
|
||||
|
||||
created_users.append((username, password))
|
||||
passwords_file_lines.append(f"Login: {username:<15} | Password: {password}")
|
||||
|
||||
if created_users:
|
||||
print("\n" + "="*80)
|
||||
print("BM - RÉGIE : UTILISATEURS CRÉÉS")
|
||||
print("="*80)
|
||||
for username, password in created_users:
|
||||
print(f" Login: {username:<15} | Mot de passe: {password}")
|
||||
print("="*80)
|
||||
|
||||
# Write to generated_passwords.txt on production server
|
||||
passwords_file_path = os.path.join(settings.BASE_DIR, 'generated_passwords.txt')
|
||||
try:
|
||||
with open(passwords_file_path, 'w', encoding='utf-8') as f:
|
||||
f.write("\n".join(passwords_file_lines) + "\n")
|
||||
print(f"Mots de passe sauvegardés dans : {passwords_file_path}")
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Impossible d'écrire les mots de passe dans un fichier: {e}")
|
||||
print("="*80 + "\n")
|
||||
|
||||
def delete_agents_regie(apps, schema_editor):
|
||||
pass
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0007_userconfig_esign_organizations'),
|
||||
('contracts', '0006_companymember_teams_m2m'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_agents_regie, reverse_code=delete_agents_regie),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-11 11:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0007_userconfig_esign_organizations'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='mobile_intervention_list_filters',
|
||||
field=models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue mobile de la liste des interventions.', verbose_name='Filtres de la liste des interventions mobile'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-11 13:39
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0008_create_agents_regie'),
|
||||
('common', '0008_userconfig_mobile_intervention_list_filters'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-16 10:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0009_merge_20260611_1539'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='project_list_filters',
|
||||
field=models.JSONField(blank=True, default=dict, help_text='Préférences de filtrage pour la vue liste des projets.', verbose_name='Filtres de la liste des projets'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='project_list_sort',
|
||||
field=models.JSONField(blank=True, default=dict, help_text='Préférences de tri pour la vue liste des projets.', verbose_name='Tri de la liste des projets'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-17 07:46
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0010_userconfig_project_list_filters_and_more'),
|
||||
('stock', '0007_add_comment_by_to_inventoryitem'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserWarehouseLocationAccess',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('can_perform_inventory', models.BooleanField(default=False, verbose_name="Peut faire l'inventaire")),
|
||||
('can_validate_inventory', models.BooleanField(default=False, verbose_name="Peut valider l'inventaire")),
|
||||
('user_config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userlocations', to='common.userconfig')),
|
||||
('warehouse_location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_accesses', to='stock.warehouselocation', verbose_name='Emplacement')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Accès Emplacement',
|
||||
'verbose_name_plural': 'Accès Emplacements',
|
||||
'unique_together': {('user_config', 'warehouse_location')},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='warehouse_locations',
|
||||
field=models.ManyToManyField(blank=True, related_name='user_configs', through='common.UserWarehouseLocationAccess', to='stock.warehouselocation'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
def create_water_thematic_and_transfer_data(apps, schema_editor):
|
||||
Thematic = apps.get_model('common', 'Thematic')
|
||||
UserThematics = apps.get_model('common', 'UserThematics')
|
||||
AssetCategory = apps.get_model('assets', 'AssetCategory')
|
||||
Symptom = apps.get_model('interventions', 'Symptom')
|
||||
InspectionConfiguration = apps.get_model('interventions', 'InspectionConfiguration')
|
||||
Intervention = apps.get_model('interventions', 'Intervention')
|
||||
|
||||
# 1. Create or get water thematic
|
||||
water_thematic, created = Thematic.objects.get_or_create(
|
||||
code='water',
|
||||
defaults={
|
||||
'name_fr': 'Eau',
|
||||
'name_nl': 'Water',
|
||||
'icon': 'bi-droplet',
|
||||
'color': '#0d6efd',
|
||||
}
|
||||
)
|
||||
|
||||
# 2. Replicate UserThematics permissions for 'water' from 'nature'
|
||||
nature_permissions = UserThematics.objects.filter(thematic__code='nature')
|
||||
for np in nature_permissions:
|
||||
UserThematics.objects.get_or_create(
|
||||
user_config=np.user_config,
|
||||
thematic=water_thematic,
|
||||
defaults={
|
||||
'can_view_assets': np.can_view_assets,
|
||||
'can_edit_assets': np.can_edit_assets,
|
||||
'can_view_interventions': np.can_view_interventions,
|
||||
'can_edit_interventions': np.can_edit_interventions,
|
||||
'can_edit_locations': np.can_edit_locations,
|
||||
'can_process_observations': np.can_process_observations,
|
||||
'can_view_projects': np.can_view_projects,
|
||||
'can_edit_projects': np.can_edit_projects,
|
||||
}
|
||||
)
|
||||
|
||||
# 3. Transfer AssetCategory NAT_RWI
|
||||
try:
|
||||
giep_cat = AssetCategory.objects.get(code='NAT_RWI')
|
||||
giep_cat.thematic = water_thematic
|
||||
giep_cat.save()
|
||||
|
||||
# Transfer any subcategories recursively (in case any exist)
|
||||
def transfer_children(parent_cat):
|
||||
for child in AssetCategory.objects.filter(parent=parent_cat):
|
||||
child.thematic = water_thematic
|
||||
child.save()
|
||||
transfer_children(child)
|
||||
transfer_children(giep_cat)
|
||||
except AssetCategory.DoesNotExist:
|
||||
pass
|
||||
|
||||
# 4. Transfer Symptom instances linked to NAT_RWI
|
||||
giep_cats = AssetCategory.objects.filter(thematic=water_thematic)
|
||||
symptoms_to_transfer = Symptom.objects.filter(
|
||||
models.Q(thematic__code='nature') &
|
||||
(models.Q(asset_categories__in=giep_cats) | models.Q(name_fr__icontains='giep') | models.Q(name_nl__icontains='giep'))
|
||||
).distinct()
|
||||
for symp in symptoms_to_transfer:
|
||||
symp.thematic = water_thematic
|
||||
symp.save()
|
||||
|
||||
# 5. Transfer InspectionConfiguration
|
||||
configs_to_transfer = InspectionConfiguration.objects.filter(
|
||||
models.Q(thematic__code='nature') &
|
||||
(models.Q(name_fr__icontains='giep') | models.Q(name_nl__icontains='giep') | models.Q(default_category__thematic=water_thematic))
|
||||
).distinct()
|
||||
for config in configs_to_transfer:
|
||||
config.thematic = water_thematic
|
||||
config.save()
|
||||
|
||||
# 6. Transfer Interventions
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
try:
|
||||
rwiz_ct = ContentType.objects.get(app_label='assets', model='naturerwiz')
|
||||
rwiasset_ct = ContentType.objects.get(app_label='assets', model='naturerwiasset')
|
||||
|
||||
# Interventions with category in water thematic
|
||||
itvs_by_cat = Intervention.objects.filter(thematic__code='nature', asset_category__thematic=water_thematic)
|
||||
|
||||
# Interventions with location in NatureRWIZ
|
||||
InterventionLocation = apps.get_model('interventions', 'InterventionLocation')
|
||||
itv_ids_by_loc = InterventionLocation.objects.filter(content_type=rwiz_ct).values_list('intervention_id', flat=True)
|
||||
itvs_by_loc = Intervention.objects.filter(thematic__code='nature', id__in=itv_ids_by_loc)
|
||||
|
||||
# Interventions with asset in NatureRWIAsset
|
||||
InterventionAsset = apps.get_model('interventions', 'InterventionAsset')
|
||||
itv_ids_by_asset = InterventionAsset.objects.filter(content_type=rwiasset_ct).values_list('intervention_id', flat=True)
|
||||
itvs_by_asset = Intervention.objects.filter(thematic__code='nature', id__in=itv_ids_by_asset)
|
||||
|
||||
all_giep_itvs = (itvs_by_cat | itvs_by_loc | itvs_by_asset).distinct()
|
||||
for itv in all_giep_itvs:
|
||||
itv.thematic = water_thematic
|
||||
itv.save()
|
||||
except ContentType.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0011_userwarehouselocationaccess_and_more'),
|
||||
('assets', '0020_alter_trafficlightradarpole_model'),
|
||||
('interventions', '0016_inspectionconfiguration_show_equipment'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_water_thematic_and_transfer_data, reverse_code=migrations.RunPython.noop),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-03 09:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0012_create_water_thematic_and_transfer_data'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userthematics',
|
||||
name='can_validate_assets',
|
||||
field=models.BooleanField(default=False, verbose_name='Peut valider les assets'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-19 05:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0013_userthematics_can_validate_assets'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userconfig',
|
||||
name='panoramax_can_upload',
|
||||
field=models.BooleanField(default=False, help_text="Permet à l'utilisateur d'uploader de nouvelles photos ou vidéos 360 pour Panoramax.", verbose_name='Peut uploader des photos 360'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import contracts.models
|
||||
|
|
@ -202,6 +202,9 @@ class Migration(migrations.Migration):
|
|||
('is_provider', models.BooleanField(default=False, help_text='Indique si cette équipe est un prestataire extérieur.', verbose_name='Prestataire')),
|
||||
('can_generate_daily_report', models.BooleanField(default=False, help_text='Indique si les membres de cette équipe peuvent générer un rapport quotidien des interventions.', verbose_name='Peut générer le rapport journalier')),
|
||||
('photos_required', models.BooleanField(default=False, help_text="Si activé, au moins une photo doit être ajoutée à l'intervention avant de pouvoir la terminer.", verbose_name='Photos obligatoires')),
|
||||
('restrict_today_interventions_visibility', models.BooleanField(default=False, help_text="Si activé, les interventions ne sont visibles qu'à partir d'une certaine heure, et uniquement pour le jour même.", verbose_name='Restreindre la visibilité aux interventions du jour')),
|
||||
('visibility_start_hour', models.TimeField(blank=True, help_text='Heure locale à partir de laquelle les interventions du jour deviennent visibles (ex: 06:00:00).', null=True, verbose_name='Heure de début de visibilité')),
|
||||
('restrict_to_assigned_interventions', models.BooleanField(default=False, help_text="Si activé, les membres de cette équipe ne voient que les interventions assignées à l'équipe ou directement à un membre.", verbose_name='Restreindre aux interventions assignées')),
|
||||
('asset_categories', models.ManyToManyField(blank=True, help_text="Catégories d'assets dont cette équipe est responsable.", related_name='managing_teams', to='assets.assetcategory', verbose_name="Catégories d'assets gérées")),
|
||||
('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teams', to='contracts.company')),
|
||||
('thematics', models.ManyToManyField(blank=True, related_name='company_teams', to='common.thematic')),
|
||||
|
|
@ -230,8 +233,8 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
migrations.AddField(
|
||||
model_name='companymember',
|
||||
name='team',
|
||||
field=models.ForeignKey(blank=True, help_text='Laisser vide pour un membre non assigné à une équipe.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='contracts.companyteam', verbose_name='Équipe'),
|
||||
name='teams',
|
||||
field=models.ManyToManyField(blank=True, help_text='Équipes auxquelles ce membre appartient.', related_name='members', to='contracts.companyteam', verbose_name='Équipes'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Contract',
|
||||
|
|
@ -253,6 +256,7 @@ class Migration(migrations.Migration):
|
|||
('needs_approval', models.BooleanField(default=False, help_text="Indique si les interventions liées à ce contrat nécessitent une approbation avant d'être transmises pour traitement.", verbose_name='Nécessite une approbation')),
|
||||
('needs_checking', models.BooleanField(default=False, help_text="Indique si les interventions liées à ce contrat nécessitent une vérification avant d'être transmises pour traitement.", verbose_name='Nécessite une vérification')),
|
||||
('uses_occupations', models.BooleanField(default=False, help_text='Indique si les interventions liées à ce contrat utilisent la gestion des occupations (temps passé par membre).', verbose_name='Utilise les occupations')),
|
||||
('uses_intervention_manager', models.BooleanField(default=False, help_text="Indique si les interventions liées à ce contrat utilisent un gestionnaire d'intervention.", verbose_name="Utilise les gestionnaires d'intervention")),
|
||||
('occupations_required', models.BooleanField(default=False, help_text='Si activé, au moins une occupation doit être enregistrée avant de terminer une intervention corrective liée à ce contrat.', verbose_name='Occupations obligatoires')),
|
||||
('warn_if_no_prestation_on_processed', models.BooleanField(default=False, help_text="Si activé, un avertissement est affiché lorsque l'utilisateur tente de passer une intervention au statut 'Traité' sans avoir encodé de prestation.", verbose_name="Avertir si aucune prestation au passage à 'Traité'")),
|
||||
('send_daily_summary', models.BooleanField(default=False, help_text="Si activé, les fiches d'intervention du jour sont regroupées dans un seul email envoyé en fin de journée, plutôt qu'un email par intervention.", verbose_name='Envoi groupé journalier')),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -10,7 +10,7 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
('common', '0004_initial'),
|
||||
('contracts', '0001_initial'),
|
||||
('projects', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-03 15:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0002_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contract',
|
||||
name='uses_intervention_manager',
|
||||
field=models.BooleanField(default=False, help_text="Indique si les interventions liées à ce contrat utilisent un gestionnaire d'intervention.", verbose_name="Utilise les gestionnaires d'intervention"),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-07 09:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0003_contract_uses_intervention_manager'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contract',
|
||||
name='auto_close_delay_days',
|
||||
field=models.PositiveIntegerField(default=30, help_text='Délai en jours après lequel une intervention est clôturée automatiquement.', verbose_name='Délai de clôture automatique (jours)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contract',
|
||||
name='auto_close_interventions',
|
||||
field=models.BooleanField(default=False, help_text='Indique si les interventions liées à ce contrat doivent être automatiquement clôturées après un certain délai.', verbose_name='Clôture automatique des interventions'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0004_contract_auto_close_delay_days_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='contract',
|
||||
name='auto_close_delay_days',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='contract',
|
||||
name='auto_close_interventions',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-10 08:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
def copy_team_to_teams(apps, schema_editor):
|
||||
CompanyMember = apps.get_model('contracts', 'CompanyMember')
|
||||
for member in CompanyMember.objects.all():
|
||||
# access the raw DB field team_id to avoid django loading issues if team FK field is already removed or modified
|
||||
team_id = getattr(member, 'team_id', None)
|
||||
if team_id is not None:
|
||||
member.teams.add(team_id)
|
||||
|
||||
def copy_teams_to_team(apps, schema_editor):
|
||||
CompanyMember = apps.get_model('contracts', 'CompanyMember')
|
||||
for member in CompanyMember.objects.all():
|
||||
first_team = member.teams.first()
|
||||
if first_team:
|
||||
member.team = first_team
|
||||
member.save(update_fields=['team'])
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0005_remove_contract_auto_close'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='companymember',
|
||||
name='teams',
|
||||
field=models.ManyToManyField(blank=True, help_text='Équipes auxquelles ce membre appartient.', related_name='members', to='contracts.companyteam', verbose_name='Équipes'),
|
||||
),
|
||||
migrations.RunPython(copy_team_to_teams, reverse_code=copy_teams_to_team),
|
||||
migrations.RemoveField(
|
||||
model_name='companymember',
|
||||
name='team',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-17 14:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0006_companymember_teams_m2m'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='companyteam',
|
||||
name='restrict_today_interventions_visibility',
|
||||
field=models.BooleanField(default=False, help_text="Si activé, les interventions ne sont visibles qu'à partir d'une certaine heure, et uniquement pour le jour même.", verbose_name='Restreindre la visibilité aux interventions du jour'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='companyteam',
|
||||
name='visibility_start_hour',
|
||||
field=models.TimeField(blank=True, help_text='Heure locale à partir de laquelle les interventions du jour deviennent visibles (ex: 06:00:00).', null=True, verbose_name='Heure de début de visibilité'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-22 09:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0007_companyteam_restrict_today_interventions_visibility_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='companyteam',
|
||||
name='restrict_to_assigned_interventions',
|
||||
field=models.BooleanField(default=False, help_text="Si activé, les membres de cette équipe ne voient que les interventions assignées à l'équipe ou directement à un membre.", verbose_name='Restreindre aux interventions assignées'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
@ -105,6 +105,18 @@ class Migration(migrations.Migration):
|
|||
'ordering': ['control', 'remark_number'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RemarkHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('status', models.CharField(choices=[('information', 'Info'), ('to_be_processed', 'NOK'), ('processed', 'Traité'), ('validated', 'OK'), ('canceled', 'Annulé')], default='to_be_processed')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RemarkImage',
|
||||
fields=[
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -10,7 +10,7 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
('common', '0004_initial'),
|
||||
('contracts', '0002_initial'),
|
||||
('controls', '0002_initial'),
|
||||
('documents', '0001_initial'),
|
||||
|
|
@ -109,6 +109,21 @@ class Migration(migrations.Migration):
|
|||
name='remark',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quantities', to='controls.remark'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='remarkhistory',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='remarkhistory',
|
||||
name='remark',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history', to='controls.remark'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='remarkimage',
|
||||
name='history_entry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='images', to='controls.remarkhistory'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='remarkimage',
|
||||
name='managed_document',
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-23 13:10
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('controls', '0003_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RemarkHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('status', models.CharField(choices=[('information', 'Info'), ('to_be_processed', 'NOK'), ('processed', 'Traité'), ('validated', 'OK'), ('canceled', 'Annulé')], default='to_be_processed')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||
('remark', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history', to='controls.remark')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['created_at'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='remarkimage',
|
||||
name='history_entry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='images', to='controls.remarkhistory'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.db.models.deletion
|
||||
|
|
@ -122,6 +122,8 @@ class Migration(migrations.Migration):
|
|||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('is_archived', models.BooleanField(default=False, verbose_name='Archived')),
|
||||
('unique_params', models.JSONField(blank=True, default=dict, help_text="Additional parameters to determine uniqueness for documents with unique tags (e.g., {'format': 'pdf', 'cables': 'C1,C2'})", verbose_name='Unique parameters')),
|
||||
('georeference_coords', models.JSONField(blank=True, help_text='Coordinates of the 4 corners: [[lng, lat], [lng, lat], [lng, lat], [lng, lat]]', null=True, verbose_name='Georeference Coordinates')),
|
||||
('georeference_page', models.IntegerField(default=1, help_text='Specific page of the PDF that has been georeferenced', verbose_name='Georeference Page')),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_documents', to=settings.AUTH_USER_MODEL, verbose_name='Created by')),
|
||||
('current_version', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='current_for_documents', to='documents.documentversion', verbose_name='Current version')),
|
||||
('folders', models.ManyToManyField(blank=True, related_name='documents', to='documents.documentfolder', verbose_name='Folders')),
|
||||
|
|
|
|||
|
|
@ -1,100 +0,0 @@
|
|||
# Generated by hand
|
||||
|
||||
from django.db import migrations
|
||||
from django.utils.text import slugify
|
||||
|
||||
|
||||
def create_giep_folders(apps, schema_editor):
|
||||
DocumentFolder = apps.get_model('documents', 'DocumentFolder')
|
||||
DocumentFolderAttachment = apps.get_model('documents', 'DocumentFolderAttachment')
|
||||
NatureRWIZ = apps.get_model('assets', 'NatureRWIZ')
|
||||
Thematic = apps.get_model('common', 'Thematic')
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
|
||||
# 1. Get or create 'assets' folder
|
||||
assets_folder, _ = DocumentFolder.objects.get_or_create(
|
||||
slug='assets',
|
||||
defaults={'name': 'Assets', 'is_predefined': True}
|
||||
)
|
||||
|
||||
# 2. Get water thematic
|
||||
water_thematic = Thematic.objects.filter(code='water').first()
|
||||
|
||||
# Create 'other' document tag
|
||||
DocumentTag = apps.get_model('documents', 'DocumentTag')
|
||||
other_tag, _ = DocumentTag.objects.get_or_create(
|
||||
slug='other',
|
||||
defaults={
|
||||
'name_fr': 'Autre',
|
||||
'name_nl': 'Andere',
|
||||
'show_in_asset_detail': True
|
||||
}
|
||||
)
|
||||
if water_thematic:
|
||||
other_tag.thematics.add(water_thematic)
|
||||
|
||||
# 3. Create 'water' folder as child of 'assets'
|
||||
water_folder, _ = DocumentFolder.objects.get_or_create(
|
||||
slug='water',
|
||||
defaults={
|
||||
'name': 'Water',
|
||||
'is_predefined': True,
|
||||
}
|
||||
)
|
||||
if water_thematic:
|
||||
water_folder.thematics.add(water_thematic)
|
||||
water_folder.parent_folders.add(assets_folder)
|
||||
|
||||
# 4. Create subfolder for each GIEP zone (NatureRWIZ)
|
||||
nature_rwiz_content_type = ContentType.objects.get_for_model(NatureRWIZ)
|
||||
|
||||
for zone in NatureRWIZ.objects.all():
|
||||
# Avoid creating duplicate folders for the same GIEP zone
|
||||
exists = DocumentFolderAttachment.objects.filter(
|
||||
content_type=nature_rwiz_content_type,
|
||||
object_id=zone.id,
|
||||
is_default=True
|
||||
).exists()
|
||||
if exists:
|
||||
continue
|
||||
|
||||
folder_name = zone.code
|
||||
base_slug = slugify(folder_name) or f"giep-{zone.id}"
|
||||
slug = base_slug
|
||||
counter = 1
|
||||
while DocumentFolder.objects.filter(slug=slug).exists():
|
||||
slug = f"{base_slug}-{counter}"
|
||||
counter += 1
|
||||
|
||||
zone_folder = DocumentFolder.objects.create(
|
||||
name=folder_name,
|
||||
slug=slug,
|
||||
is_predefined=True
|
||||
)
|
||||
if water_thematic:
|
||||
zone_folder.thematics.add(water_thematic)
|
||||
zone_folder.parent_folders.add(water_folder)
|
||||
|
||||
# Attach folder to NatureRWIZ
|
||||
DocumentFolderAttachment.objects.create(
|
||||
folder=zone_folder,
|
||||
content_type=nature_rwiz_content_type,
|
||||
object_id=zone.id,
|
||||
is_default=True
|
||||
)
|
||||
|
||||
|
||||
def remove_giep_folders(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('documents', '0001_initial'),
|
||||
('assets', '0020_alter_trafficlightradarpole_model'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(create_giep_folders, remove_giep_folders),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-04 06:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('documents', '0002_create_giep_folders'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='manageddocument',
|
||||
name='georeference_coords',
|
||||
field=models.JSONField(blank=True, help_text='Coordinates of the 4 corners: [[lng, lat], [lng, lat], [lng, lat], [lng, lat]]', null=True, verbose_name='Georeference Coordinates'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='manageddocument',
|
||||
name='georeference_page',
|
||||
field=models.IntegerField(default=1, help_text='Specific page of the PDF that has been georeferenced', verbose_name='Georeference Page'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
|
@ -18,7 +18,7 @@ class Migration(migrations.Migration):
|
|||
name='HomeWidget',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('widget_code', models.CharField(choices=[('intervention_stats', 'Statistiques interventions'), ('contracts_summary', 'Résumé contrats'), ('map_today', 'Carte du jour'), ('operator_shortcuts', 'Raccourcis opérateur'), ('assets_links', 'Liens assets'), ('stock_summary', 'Résumé stock'), ('observer_shortcuts', 'Raccourcis observateur'), ('incident_counter', 'Compteur incidents à traiter'), ('intervention_to_verify', 'Compteur interventions à vérifier'), ('intervention_to_plan', 'Compteur interventions à planifier'), ('intervention_to_approve', 'Compteur interventions à approuver'), ('intervention_checked_to_approve', 'Compteur interventions vérifiées à approuver'), ('stock_actions', 'Actions stock')], max_length=50, unique=True, verbose_name='Code du widget')),
|
||||
('widget_code', models.CharField(choices=[('intervention_stats', 'Statistiques interventions'), ('contracts_summary', 'Résumé contrats'), ('map_today', 'Carte du jour'), ('operator_shortcuts', 'Raccourcis opérateur'), ('assets_links', 'Liens assets'), ('stock_summary', 'Résumé stock'), ('observer_shortcuts', 'Raccourcis observateur'), ('incident_counter', 'Compteur incidents à traiter'), ('intervention_to_verify', 'Compteur interventions à vérifier'), ('intervention_to_plan', 'Compteur interventions à planifier'), ('intervention_to_approve', 'Compteur interventions à approuver'), ('intervention_checked_to_approve', 'Compteur interventions vérifiées à approuver'), ('intervention_finished', 'Compteur interventions terminées'), ('stock_actions', 'Actions stock')], max_length=50, unique=True, verbose_name='Code du widget')),
|
||||
('default_template_override', models.CharField(blank=True, help_text='Chemin du template optionnel (sinon home/widgets/<widget_code>.html)', max_length=255, null=True, verbose_name='Template par défaut (surcharge)')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='Actif')),
|
||||
],
|
||||
|
|
@ -28,6 +28,22 @@ class Migration(migrations.Migration):
|
|||
'ordering': ['widget_code'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TeambuildingVote',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('voter_name', models.CharField(blank=True, max_length=100, null=True, verbose_name='Nom (optionnel)')),
|
||||
('vote_gael', models.IntegerField(default=0, verbose_name="La journée 'Gaël Non Di Dju'")),
|
||||
('vote_charly', models.IntegerField(default=0, verbose_name="La journée 'La cité de Charly'")),
|
||||
('vote_tequila', models.IntegerField(default=0, verbose_name="La journée 'Tequila Cadena'")),
|
||||
('vote_vivien', models.IntegerField(default=0, verbose_name="La journée 'Vivien de La Grande Propreté'")),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Vote Teambuilding',
|
||||
'verbose_name_plural': 'Votes Teambuilding',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HomeWidgetConditionGroup',
|
||||
fields=[
|
||||
|
|
@ -53,6 +69,7 @@ class Migration(migrations.Migration):
|
|||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('condition_type', models.CharField(choices=[('role', 'Rôle'), ('team', 'Équipe'), ('contract', 'Contrat'), ('thematic', 'Thématique'), ('is_intern', 'Statut interne')], max_length=20, verbose_name='Type de condition')),
|
||||
('is_intern', models.BooleanField(blank=True, help_text="Utilisé si type = 'is_intern'", null=True, verbose_name='Statut interne')),
|
||||
('is_negated', models.BooleanField(default=False, help_text='Inverser le sens de la condition (ex: NOT role=Admin)', verbose_name='NOT')),
|
||||
('is_active', models.BooleanField(default=True, verbose_name='Actif')),
|
||||
('contract', models.ForeignKey(blank=True, help_text="Utilisé si type = 'contract'", null=True, on_delete=django.db.models.deletion.CASCADE, to='contracts.contract', verbose_name='Contrat')),
|
||||
('role', models.ForeignKey(blank=True, help_text="Utilisé si type = 'role'", null=True, on_delete=django.db.models.deletion.CASCADE, to='common.role', verbose_name='Rôle')),
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-03 09:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='homewidget',
|
||||
name='widget_code',
|
||||
field=models.CharField(choices=[('intervention_stats', 'Statistiques interventions'), ('contracts_summary', 'Résumé contrats'), ('map_today', 'Carte du jour'), ('operator_shortcuts', 'Raccourcis opérateur'), ('assets_links', 'Liens assets'), ('stock_summary', 'Résumé stock'), ('observer_shortcuts', 'Raccourcis observateur'), ('incident_counter', 'Compteur incidents à traiter'), ('intervention_to_verify', 'Compteur interventions à vérifier'), ('intervention_to_plan', 'Compteur interventions à planifier'), ('intervention_to_approve', 'Compteur interventions à approuver'), ('intervention_checked_to_approve', 'Compteur interventions vérifiées à approuver'), ('intervention_finished', 'Compteur interventions terminées'), ('stock_actions', 'Actions stock')], max_length=50, unique=True, verbose_name='Code du widget'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-03 09:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0002_alter_homewidget_widget_code'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='homewidgetcondition',
|
||||
name='is_negated',
|
||||
field=models.BooleanField(default=False, help_text='Inverser le sens de la condition (ex: NOT role=Admin)', verbose_name='NOT'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-18 08:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0003_homewidgetcondition_is_negated'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TeambuildingVote',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('voter_name', models.CharField(blank=True, max_length=100, null=True, verbose_name='Nom (optionnel)')),
|
||||
('vote_gael', models.IntegerField(default=0, verbose_name="La journée 'Gaël Non Di Dju'")),
|
||||
('vote_charly', models.IntegerField(default=0, verbose_name="La journée 'La cité de Charly'")),
|
||||
('vote_tequila', models.IntegerField(default=0, verbose_name="La journée 'Tequila Cadena'")),
|
||||
('vote_vivien', models.IntegerField(default=0, verbose_name="La journée 'Vivien de La Grande Propreté'")),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Vote Teambuilding',
|
||||
'verbose_name_plural': 'Votes Teambuilding',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
|||
|
||||
dependencies = [
|
||||
('assets', '0003_initial'),
|
||||
('common', '0002_initial'),
|
||||
('common', '0003_initial'),
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('contracts', '0001_initial'),
|
||||
('documents', '0001_initial'),
|
||||
|
|
@ -153,13 +153,13 @@ class Migration(migrations.Migration):
|
|||
('location_code', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('status', models.CharField(choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], default='in_preparation')),
|
||||
('status_order', models.IntegerField(default=1)),
|
||||
('pause_reason', models.CharField(blank=True, choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('other', 'Autre')], max_length=50, null=True)),
|
||||
('pause_reason', models.CharField(blank=True, choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('waiting_for_material_delivery', 'En attente livraison de matériel'), ('waiting_for_supplier', 'En attente sous-traitant'), ('offer_by_provider', 'Offre à faire par le prestataire'), ('waiting_for_validation', 'En attente de validation'), ('under_framework_contract', 'Sous garantie marché transversal'), ('other', 'Autre')], max_length=50, null=True)),
|
||||
('pause_reason_other', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('cancellation_type', models.CharField(blank=True, choices=[('duplicate', 'Doublon'), ('to_redirect', 'A rediriger'), ('not_our_assets', 'Pas sous notre gestion'), ('non_relevant', 'Non-relevant'), ('other', 'Autre')], max_length=50, null=True)),
|
||||
('priority', models.CharField(choices=[('1', 'Urgent'), ('2', 'Elevé'), ('3', 'Normal'), ('4', 'Bas')], default='3')),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('maintain_type', models.CharField(choices=[('corrective', 'Maintenance corrective'), ('preventive', 'Maintenance préventive'), ('ameliorative', 'Maintenance améliorative')], default='corrective')),
|
||||
('type', models.CharField(blank=True, choices=[('fixing', 'Dépannage'), ('repair', 'Réparation'), ('repair_post_preventive', 'Réparation post préventif'), ('replace', 'Remplacement'), ('care', 'Entretien'), ('control', 'Contrôle'), ('inspection', 'Inspection'), ('build', 'Construction')], null=True)),
|
||||
('type', models.CharField(blank=True, choices=[('fixing', 'Dépannage'), ('repair', 'Réparation'), ('repair_post_preventive', 'Réparation post préventif'), ('replace', 'Remplacement'), ('care', 'Entretien'), ('control', 'Contrôle'), ('inspection', 'Inspection'), ('build', 'Construction'), ('collection', 'Ramassage')], null=True)),
|
||||
('origin_type', models.CharField(choices=[('damage', 'Avarie'), ('defect', 'Défaut/Panne'), ('demand', 'Demande')], default='damage')),
|
||||
('begin_time', models.DateTimeField(blank=True, null=True)),
|
||||
('end_time', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -198,6 +198,7 @@ class Migration(migrations.Migration):
|
|||
('contract', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interventions', to='contracts.contract')),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='created_interventions', to=settings.AUTH_USER_MODEL)),
|
||||
('guided_operation_template', models.ForeignKey(blank=True, help_text="Assigné automatiquement lors du choix d'un template d'opérations avec un template guidé associé.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interventions', to='interventions.guidedoperationtemplate', verbose_name="Template d'opérations guidées")),
|
||||
('intervention_manager', models.ForeignKey(blank=True, help_text='Utilisateur qui approuve cette intervention (spécifique aux contrats concernés).', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='managed_interventions', to=settings.AUTH_USER_MODEL, verbose_name="Gestionnaire d'intervention")),
|
||||
('last_modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='modified_interventions', to=settings.AUTH_USER_MODEL)),
|
||||
('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interventions', to='contracts.contractorder')),
|
||||
('thematic', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='common.thematic')),
|
||||
|
|
@ -413,6 +414,28 @@ class Migration(migrations.Migration):
|
|||
name='equipment_operation_templates',
|
||||
field=models.ManyToManyField(blank=True, related_name='interventions_equipment', to='interventions.operationtemplate'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfiguration',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name_fr', models.CharField(max_length=255, verbose_name='Nom (FR)')),
|
||||
('name_nl', models.CharField(blank=True, max_length=255, verbose_name='Nom (NL)')),
|
||||
('description', models.TextField(blank=True, verbose_name='Description')),
|
||||
('maintain_type', models.CharField(choices=[('corrective', 'Maintenance corrective'), ('preventive', 'Maintenance préventive'), ('ameliorative', 'Maintenance améliorative')], default='preventive', max_length=50, verbose_name='Type de maintenance')),
|
||||
('show_equipment', models.BooleanField(default=True, help_text="Si décoché, le champ équipement sera masqué lors de l'encodage de cette inspection.", verbose_name='Afficher le champ équipement')),
|
||||
('concerned_categories', models.ManyToManyField(blank=True, help_text='Filtre les localisations et équipements affichés sur la carte par catégorie. Si vide, tous sont affichés.', related_name='inspection_configs', to='assets.assetcategory', verbose_name='Catégories concernées')),
|
||||
('default_category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory', verbose_name='Catégorie par défaut')),
|
||||
('displayed_asset_types', models.ManyToManyField(blank=True, limit_choices_to=models.Q(('app_label', 'assets')), related_name='inspection_configs_as_asset', to='contenttypes.contenttype', verbose_name="Types d'équipements à afficher sur la carte")),
|
||||
('displayed_location_types', models.ManyToManyField(blank=True, limit_choices_to=models.Q(('app_label', 'assets')), related_name='inspection_configs_as_location', to='contenttypes.contenttype', verbose_name='Types de localisations à afficher sur la carte')),
|
||||
('thematic', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='common.thematic', verbose_name='Thématique')),
|
||||
('operation_templates', models.ManyToManyField(blank=True, to='interventions.operationtemplate', verbose_name="Templates d'opérations")),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Configuration d'inspection",
|
||||
'verbose_name_plural': "Configurations d'inspections",
|
||||
'ordering': ['name_fr'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OperationTemplateItem',
|
||||
fields=[
|
||||
|
|
@ -448,9 +471,12 @@ class Migration(migrations.Migration):
|
|||
('check_priority', models.BooleanField(default=False, help_text='Indique si la priorité doit être vérifiée.')),
|
||||
('origin_type', models.CharField(blank=True, choices=[('damage', 'Avarie'), ('defect', 'Défaut/Panne'), ('demand', 'Demande')], default='damage', null=True)),
|
||||
('maintenance_type', models.CharField(blank=True, choices=[('infra', 'TL - Infrastructure'), ('controller', 'TL - Contrôleur de traffic'), ('electromeca', 'TU - Electromécanique'), ('civil_engineering', 'TU - Génie civil'), ('equipments', 'ITS - Équipement'), ('clean', 'Clean - Nettoyage'), ('collection', 'Clean - Ramassage'), ('other', 'Autre')], help_text="Type de maintenance concerné (ex: 'controller' pour les contrôleurs de traffic).", max_length=50, null=True)),
|
||||
('require_equipment_selection', models.BooleanField(default=False, help_text='Si coché, une intervention avec ce symptôme doit obligatoirement être liée à un équipement.', verbose_name='Équipement obligatoire')),
|
||||
('order_number', models.IntegerField(blank=True, null=True)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('recommended_next_status', models.CharField(blank=True, choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], default='to_be_processed', max_length=50, null=True)),
|
||||
('auto_create_intervention', models.BooleanField(default=False, help_text="Si coché, une intervention est automatiquement créée lorsque l'observation passe au statut 'À traiter'.", verbose_name="Création automatique d'interventions")),
|
||||
('auto_create_intervention_status', models.CharField(blank=True, choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], default='to_be_processed', help_text="Statut dans lequel l'intervention automatique doit être créée.", max_length=50, null=True, verbose_name="Statut de l'intervention auto-créée")),
|
||||
('internal_notification_emails', models.CharField(blank=True, help_text="Liste d'emails pour les notifications internes.", max_length=1000, null=True)),
|
||||
('asset_categories', models.ManyToManyField(blank=True, related_name='symptoms', to='assets.assetcategory')),
|
||||
('contract', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contracts.contract')),
|
||||
|
|
@ -487,6 +513,34 @@ class Migration(migrations.Migration):
|
|||
name='symptom',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='interventions.symptom'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DirectContractRouting',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('thematic', models.CharField(choices=[('structures', 'Structures'), ('trafficlights', 'Traffic Lights'), ('clean', 'Clean'), ('its', 'ITS'), ('nature', 'Nature'), ('roads', 'Roads'), ('publiclighting', 'Public Lighting')], max_length=50, verbose_name='Thématique')),
|
||||
('asset_code', models.CharField(help_text="Le code de l'ouvrage d'art ou de l'équipement concerné.", max_length=100, verbose_name="Code de l'asset (ex: OA054)")),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contracts.contract', verbose_name='Contrat à forcer')),
|
||||
('symptom', models.ForeignKey(blank=True, help_text="Si renseigné, cette règle s'applique uniquement à ce symptôme. Sinon, elle s'applique par défaut.", null=True, on_delete=django.db.models.deletion.CASCADE, to='interventions.symptom', verbose_name='Symptôme spécifique')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Routage direct de contrat',
|
||||
'verbose_name_plural': 'Routages directs de contrats',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SymptomContractAutoClose',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('delay_days', models.PositiveIntegerField(default=30, help_text="Délai en jours après lequel l'intervention est clôturée automatiquement.", verbose_name='Délai (jours)')),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_close_rules', to='contracts.contract', verbose_name='Contrat')),
|
||||
('symptom', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_close_rules', to='interventions.symptom', verbose_name='Symptôme')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Règle de clôture automatique (symptôme × contrat)',
|
||||
'verbose_name_plural': 'Règles de clôture automatique (symptôme × contrat)',
|
||||
'ordering': ['symptom', 'contract'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SymptomRecommendation',
|
||||
fields=[
|
||||
|
|
@ -507,7 +561,7 @@ class Migration(migrations.Migration):
|
|||
name='ContractPauseReasonAssignment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('pause_reason', models.CharField(choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('other', 'Autre')], max_length=50, verbose_name='Motif de pause')),
|
||||
('pause_reason', models.CharField(choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('waiting_for_material_delivery', 'En attente livraison de matériel'), ('waiting_for_supplier', 'En attente sous-traitant'), ('offer_by_provider', 'Offre à faire par le prestataire'), ('waiting_for_validation', 'En attente de validation'), ('under_framework_contract', 'Sous garantie marché transversal'), ('other', 'Autre')], max_length=50, verbose_name='Motif de pause')),
|
||||
('assigned_member', models.ForeignKey(blank=True, help_text="Membre à qui réassigner automatiquement l'intervention lors d'une mise en pause avec ce motif. Laisser vide pour désassigner.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pause_reason_assignments', to='contracts.companymember', verbose_name='Membre assigné')),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pause_reason_assignments', to='contracts.contract', verbose_name='Contrat')),
|
||||
],
|
||||
|
|
@ -517,6 +571,38 @@ class Migration(migrations.Migration):
|
|||
'unique_together': {('contract', 'pause_reason')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfigurationContract',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inspection_configuration_contracts', to='contracts.contract', verbose_name='Contrat')),
|
||||
('inspection_configuration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contracts_providers', to='interventions.inspectionconfiguration', verbose_name="Configuration d'inspection")),
|
||||
('provider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inspection_configuration_contracts', to='contracts.company', verbose_name='Prestataire')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Prestataire et Contrat d'inspection",
|
||||
'verbose_name_plural': "Prestataires et Contrats d'inspections",
|
||||
'unique_together': {('inspection_configuration', 'provider', 'contract')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InterventionAssignment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('status', models.CharField(blank=True, choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], max_length=50, null=True, verbose_name='Statut')),
|
||||
('date', models.DateField(verbose_name="Date d'assignation")),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_assignments', to='interventions.intervention', verbose_name='Intervention')),
|
||||
('member', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='daily_assignments', to='contracts.companymember', verbose_name='Membre')),
|
||||
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_assignments', to='contracts.companyteam', verbose_name='Équipe')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Assignation quotidienne d'intervention",
|
||||
'verbose_name_plural': "Assignations quotidiennes d'interventions",
|
||||
'ordering': ['date', 'team'],
|
||||
'unique_together': {('intervention', 'date')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InterventionLink',
|
||||
fields=[
|
||||
|
|
@ -561,6 +647,20 @@ class Migration(migrations.Migration):
|
|||
'unique_together': {('intervention', 'contract_post', 'period_number')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InterventionSubscription',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Abonné le')),
|
||||
('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriptions', to='interventions.intervention', verbose_name='Intervention')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='intervention_subscriptions', to=settings.AUTH_USER_MODEL, verbose_name='Utilisateur')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Abonnement à une intervention',
|
||||
'verbose_name_plural': 'Abonnements aux interventions',
|
||||
'unique_together': {('user', 'intervention')},
|
||||
},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='operationstatus',
|
||||
unique_together={('status_set', 'value')},
|
||||
|
|
@ -603,4 +703,12 @@ class Migration(migrations.Migration):
|
|||
model_name='intervention',
|
||||
index=models.Index(fields=['begin_time', 'planned_begin_time', 'expected_begin_time', 'maintain_type'], name='intv_chart_begin_maintain_idx'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='directcontractrouting',
|
||||
unique_together={('thematic', 'asset_code', 'symptom')},
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='symptomcontractautoclose',
|
||||
unique_together={('symptom', 'contract')},
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-24 08:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='intervention',
|
||||
name='type',
|
||||
field=models.CharField(blank=True, choices=[('fixing', 'Dépannage'), ('repair', 'Réparation'), ('repair_post_preventive', 'Réparation post préventif'), ('replace', 'Remplacement'), ('care', 'Entretien'), ('control', 'Contrôle'), ('inspection', 'Inspection'), ('build', 'Construction'), ('collection', 'Ramassage')], null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-28 12:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0005_userconfig_calendar_preferences'),
|
||||
('contracts', '0002_initial'),
|
||||
('interventions', '0002_alter_intervention_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfiguration',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name_fr', models.CharField(max_length=255, verbose_name='Nom (FR)')),
|
||||
('name_nl', models.CharField(blank=True, max_length=255, verbose_name='Nom (NL)')),
|
||||
('description', models.TextField(blank=True, verbose_name='Description')),
|
||||
('maintain_type', models.CharField(choices=[('corrective', 'Maintenance corrective'), ('preventive', 'Maintenance préventive'), ('ameliorative', 'Maintenance améliorative')], default='preventive', max_length=50, verbose_name='Type de maintenance')),
|
||||
('assigned_provider', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inspection_configs', to='contracts.company', verbose_name='Prestataire')),
|
||||
('contract', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inspection_configs', to='contracts.contract', verbose_name='Contrat')),
|
||||
('operation_templates', models.ManyToManyField(blank=True, to='interventions.operationtemplate', verbose_name="Templates d'opérations")),
|
||||
('thematic', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='common.thematic', verbose_name='Thématique')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Configuration d'inspection",
|
||||
'verbose_name_plural': "Configurations d'inspections",
|
||||
'ordering': ['name_fr'],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-28 14:19
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def migrate_existing_inspection_configs(apps, schema_editor):
|
||||
InspectionConfiguration = apps.get_model('interventions', 'InspectionConfiguration')
|
||||
InspectionConfigurationContract = apps.get_model('interventions', 'InspectionConfigurationContract')
|
||||
|
||||
for config in InspectionConfiguration.objects.all():
|
||||
if config.contract_id and config.assigned_provider_id:
|
||||
InspectionConfigurationContract.objects.get_or_create(
|
||||
inspection_configuration=config,
|
||||
contract_id=config.contract_id,
|
||||
provider_id=config.assigned_provider_id
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0002_initial'),
|
||||
('interventions', '0003_inspectionconfiguration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfigurationContract',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inspection_configuration_contracts', to='contracts.contract', verbose_name='Contrat')),
|
||||
('inspection_configuration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contracts_providers', to='interventions.inspectionconfiguration', verbose_name="Configuration d'inspection")),
|
||||
('provider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inspection_configuration_contracts', to='contracts.company', verbose_name='Prestataire')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Prestataire et Contrat d'inspection",
|
||||
'verbose_name_plural': "Prestataires et Contrats d'inspections",
|
||||
'unique_together': {('inspection_configuration', 'provider', 'contract')},
|
||||
},
|
||||
),
|
||||
migrations.RunPython(migrate_existing_inspection_configs, reverse_code=migrations.RunPython.noop),
|
||||
]
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-28 14:20
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0004_inspectionconfigurationcontract'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='assigned_provider',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='contract',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-28 14:43
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0008_delete_naturehollowgreenspace'),
|
||||
('interventions', '0005_remove_inspectionconfiguration_assigned_provider_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='default_category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.assetcategory', verbose_name='Catégorie par défaut'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-29 07:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('interventions', '0006_inspectionconfiguration_default_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfigurationAsset',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField(verbose_name="ID d'équipement")),
|
||||
('content_type', models.ForeignKey(limit_choices_to=models.Q(('app_label', 'assets')), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name="Type d'équipement")),
|
||||
('inspection_configuration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='assets', to='interventions.inspectionconfiguration', verbose_name="Configuration d'inspection")),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Équipement à afficher sur la carte',
|
||||
'verbose_name_plural': 'Équipements à afficher sur la carte',
|
||||
'unique_together': {('inspection_configuration', 'content_type', 'object_id')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InspectionConfigurationLocation',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField(verbose_name='ID de localisation')),
|
||||
('content_type', models.ForeignKey(limit_choices_to=models.Q(('app_label', 'assets')), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', verbose_name='Type de localisation')),
|
||||
('inspection_configuration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='interventions.inspectionconfiguration', verbose_name="Configuration d'inspection")),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Localisation à afficher sur la carte',
|
||||
'verbose_name_plural': 'Localisations à afficher sur la carte',
|
||||
'unique_together': {('inspection_configuration', 'content_type', 'object_id')},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-29 07:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('interventions', '0007_inspectionconfigurationasset_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='inspectionconfigurationlocation',
|
||||
unique_together=None,
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inspectionconfigurationlocation',
|
||||
name='content_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inspectionconfigurationlocation',
|
||||
name='inspection_configuration',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='displayed_asset_types',
|
||||
field=models.ManyToManyField(blank=True, limit_choices_to=models.Q(('app_label', 'assets')), related_name='inspection_configs_as_asset', to='contenttypes.contenttype', verbose_name="Types d'équipements à afficher sur la carte"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='displayed_location_types',
|
||||
field=models.ManyToManyField(blank=True, limit_choices_to=models.Q(('app_label', 'assets')), related_name='inspection_configs_as_location', to='contenttypes.contenttype', verbose_name='Types de localisations à afficher sur la carte'),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='InspectionConfigurationAsset',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='InspectionConfigurationLocation',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# Generated manually
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0008_delete_naturehollowgreenspace'),
|
||||
('interventions', '0008_alter_inspectionconfigurationlocation_unique_together_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='concerned_categories',
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
help_text="Filtre les localisations et équipements affichés sur la carte par catégorie. Si vide, tous sont affichés.",
|
||||
related_name='inspection_configs',
|
||||
to='assets.assetcategory',
|
||||
verbose_name='Catégories concernées',
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-03 15:20
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0009_inspectionconfiguration_concerned_categories'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='intervention_manager',
|
||||
field=models.ForeignKey(blank=True, help_text='Utilisateur qui approuve cette intervention (spécifique aux contrats concernés).', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='managed_interventions', to=settings.AUTH_USER_MODEL, verbose_name="Gestionnaire d'intervention"),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-07 09:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0010_intervention_intervention_manager'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='symptom',
|
||||
name='auto_close_delay_days',
|
||||
field=models.PositiveIntegerField(default=30, help_text='Délai en jours après lequel une intervention est clôturée automatiquement pour ce symptôme.', verbose_name='Délai de clôture automatique (jours)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='symptom',
|
||||
name='auto_close_interventions',
|
||||
field=models.BooleanField(default=False, help_text='Indique si les interventions liées à ce symptôme doivent être automatiquement clôturées après un certain délai.', verbose_name='Clôture automatique des interventions'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0004_contract_auto_close_delay_days_and_more'),
|
||||
('interventions', '0011_symptom_auto_close_delay_days_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SymptomContractAutoClose',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('delay_days', models.PositiveIntegerField(default=30, help_text="Délai en jours après lequel l'intervention est clôturée automatiquement.", verbose_name='Délai (jours)')),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_close_rules', to='contracts.contract', verbose_name='Contrat')),
|
||||
('symptom', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_close_rules', to='interventions.symptom', verbose_name='Symptôme')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Règle de clôture automatique (symptôme × contrat)',
|
||||
'verbose_name_plural': 'Règles de clôture automatique (symptôme × contrat)',
|
||||
'ordering': ['symptom', 'contract'],
|
||||
'unique_together': {('symptom', 'contract')},
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='symptom',
|
||||
name='auto_close_delay_days',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='symptom',
|
||||
name='auto_close_interventions',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0012_symptomcontractautoclose_remove_symptom_auto_close'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='symptom',
|
||||
name='require_equipment_selection',
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="Si coché, une intervention avec ce symptôme doit obligatoirement être liée à un équipement.",
|
||||
verbose_name='Équipement obligatoire',
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-11 13:40
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
def create_initial_assignments(apps, schema_editor):
|
||||
Intervention = apps.get_model('interventions', 'Intervention')
|
||||
InterventionAssignment = apps.get_model('interventions', 'InterventionAssignment')
|
||||
from datetime import timedelta
|
||||
|
||||
for itv in Intervention.objects.filter(assigned_team__isnull=False):
|
||||
start_dt = itv.planned_begin_time or itv.begin_time or itv.expected_begin_time or itv.creation_time
|
||||
end_dt = itv.planned_end_time or itv.end_time or itv.expected_end_time or start_dt
|
||||
if start_dt:
|
||||
start_date = start_dt.date()
|
||||
end_date = end_dt.date()
|
||||
curr = start_date
|
||||
while curr <= end_date:
|
||||
InterventionAssignment.objects.get_or_create(
|
||||
intervention=itv,
|
||||
date=curr,
|
||||
defaults={
|
||||
'team': itv.assigned_team,
|
||||
'member': itv.assigned_member,
|
||||
'status': itv.status,
|
||||
}
|
||||
)
|
||||
curr += timedelta(days=1)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0006_companymember_teams_m2m'),
|
||||
('interventions', '0013_symptom_require_equipment_selection'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InterventionAssignment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('status', models.CharField(blank=True, choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], max_length=50, null=True, verbose_name='Statut')),
|
||||
('date', models.DateField(verbose_name="Date d'assignation")),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_assignments', to='interventions.intervention', verbose_name='Intervention')),
|
||||
('member', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='daily_assignments', to='contracts.companymember', verbose_name='Membre')),
|
||||
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_assignments', to='contracts.companyteam', verbose_name='Équipe')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "Assignation quotidienne d'intervention",
|
||||
'verbose_name_plural': "Assignations quotidiennes d'interventions",
|
||||
'ordering': ['date', 'team'],
|
||||
'unique_together': {('intervention', 'date')},
|
||||
},
|
||||
),
|
||||
migrations.RunPython(
|
||||
create_initial_assignments,
|
||||
reverse_code=migrations.RunPython.noop
|
||||
),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-16 17:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0014_interventionassignment'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='symptom',
|
||||
name='auto_create_intervention',
|
||||
field=models.BooleanField(default=False, help_text="Si coché, une intervention est automatiquement créée lorsque l'observation passe au statut 'À traiter'.", verbose_name="Création automatique d'interventions"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='symptom',
|
||||
name='auto_create_intervention_status',
|
||||
field=models.CharField(blank=True, choices=[('in_preparation', 'En préparation'), ('to_be_approved', 'A approuver'), ('to_be_planned', 'A planifier'), ('to_be_processed', 'A traiter'), ('assigned', 'Pris en charge'), ('in_progress', 'Démarré'), ('on_pause', 'En pause'), ('finished', 'Terminé'), ('processed', 'Traité'), ('to_be_corrected', 'A corriger'), ('corrected', 'Corrigé'), ('validated', 'Validé'), ('invoiced', 'Comptabilisé'), ('closed', 'Finalisé'), ('canceled', 'Annulé')], default='to_be_processed', help_text="Statut dans lequel l'intervention automatique doit être créée.", max_length=50, null=True, verbose_name="Statut de l'intervention auto-créée"),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-25 13:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0015_symptom_auto_create_intervention_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='inspectionconfiguration',
|
||||
name='show_equipment',
|
||||
field=models.BooleanField(default=True, help_text="Si décoché, le champ équipement sera masqué lors de l'encodage de cette inspection.", verbose_name='Afficher le champ équipement'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-06 08:33
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0016_inspectionconfiguration_show_equipment'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InterventionSubscription',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Abonné le')),
|
||||
('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriptions', to='interventions.intervention', verbose_name='Intervention')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='intervention_subscriptions', to=settings.AUTH_USER_MODEL, verbose_name='Utilisateur')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Abonnement à une intervention',
|
||||
'verbose_name_plural': 'Abonnements aux interventions',
|
||||
'unique_together': {('user', 'intervention')},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-09 09:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0017_interventionsubscription'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contractpausereasonassignment',
|
||||
name='pause_reason',
|
||||
field=models.CharField(choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('waiting_for_material_delivery', 'En attente livraison de matériel'), ('waiting_for_supplier', 'En attente sous-traitant'), ('offer_by_provider', 'Offre à faire par le prestataire'), ('waiting_for_validation', 'En attente de validation'), ('under_framework_contract', 'Sous garantie marché transversal'), ('other', 'Autre')], max_length=50, verbose_name='Motif de pause'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='intervention',
|
||||
name='pause_reason',
|
||||
field=models.CharField(blank=True, choices=[('reschedule', 'Intervention à replanifier'), ('order_material', 'Matériel à commander'), ('treated_in_next_maintenance', 'Traité dans le prochain entretien'), ('waiting_for_material_delivery', 'En attente livraison de matériel'), ('waiting_for_supplier', 'En attente sous-traitant'), ('offer_by_provider', 'Offre à faire par le prestataire'), ('waiting_for_validation', 'En attente de validation'), ('under_framework_contract', 'Sous garantie marché transversal'), ('other', 'Autre')], max_length=50, null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-22 09:11
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contracts', '0008_companyteam_restrict_to_assigned_interventions'),
|
||||
('interventions', '0018_alter_contractpausereasonassignment_pause_reason_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DirectContractRouting',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('thematic', models.CharField(choices=[('structures', 'Structures'), ('trafficlights', 'Traffic Lights'), ('clean', 'Clean'), ('its', 'ITS'), ('nature', 'Nature'), ('roads', 'Roads'), ('publiclighting', 'Public Lighting')], max_length=50, verbose_name='Thématique')),
|
||||
('asset_code', models.CharField(help_text="Le code de l'ouvrage d'art ou de l'équipement concerné.", max_length=100, verbose_name="Code de l'asset (ex: OA054)")),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contracts.contract', verbose_name='Contrat à forcer')),
|
||||
('symptom', models.ForeignKey(blank=True, help_text="Si renseigné, cette règle s'applique uniquement à ce symptôme. Sinon, elle s'applique par défaut.", null=True, on_delete=django.db.models.deletion.CASCADE, to='interventions.symptom', verbose_name='Symptôme spécifique')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Routage direct de contrat',
|
||||
'verbose_name_plural': 'Routages directs de contrats',
|
||||
'unique_together': {('thematic', 'asset_code', 'symptom')},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-22 09:42
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def inject_oa054_routing(apps, schema_editor):
|
||||
DirectContractRouting = apps.get_model('interventions', 'DirectContractRouting')
|
||||
Contract = apps.get_model('contracts', 'Contract')
|
||||
Symptom = apps.get_model('interventions', 'Symptom')
|
||||
|
||||
# Find the contracts
|
||||
contract_x005 = Contract.objects.filter(contract_number='X00.005').first()
|
||||
contract_x006 = Contract.objects.filter(contract_number='X00.006').first()
|
||||
symptom_clean = Symptom.objects.filter(code='TU_CLEAN_ROADWAY').first()
|
||||
|
||||
# If X00.005 and TU_CLEAN_ROADWAY symptom exist, create the routing rule
|
||||
if contract_x005 and symptom_clean:
|
||||
DirectContractRouting.objects.get_or_create(
|
||||
thematic='structures',
|
||||
asset_code='OA054',
|
||||
symptom=symptom_clean,
|
||||
defaults={'contract': contract_x005}
|
||||
)
|
||||
|
||||
# If X00.006 exists, create the default routing rule for OA054
|
||||
if contract_x006:
|
||||
DirectContractRouting.objects.get_or_create(
|
||||
thematic='structures',
|
||||
asset_code='OA054',
|
||||
symptom=None,
|
||||
defaults={'contract': contract_x006}
|
||||
)
|
||||
|
||||
|
||||
def reverse_oa054_routing(apps, schema_editor):
|
||||
DirectContractRouting = apps.get_model('interventions', 'DirectContractRouting')
|
||||
DirectContractRouting.objects.filter(thematic='structures', asset_code='OA054').delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interventions', '0019_directcontractrouting'),
|
||||
('contracts', '__first__'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(inject_oa054_routing, reverse_code=reverse_oa054_routing),
|
||||
]
|
||||
|
|
@ -712,7 +712,7 @@ class InterventionLink(models.Model):
|
|||
name="uniq_intervention_link",
|
||||
),
|
||||
models.CheckConstraint(
|
||||
check=~Q(first=F("second")),
|
||||
condition=~Q(first=F("second")),
|
||||
name="prevent_self_link",
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
import notifications.models
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
@ -143,7 +143,7 @@ class Migration(migrations.Migration):
|
|||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('observation_type', models.CharField(choices=[('incident', 'Incident'), ('inventory', 'Inventaire'), ('remark', 'Remarque')], default='incident', max_length=20)),
|
||||
('geom', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=3812)),
|
||||
('status', models.CharField(choices=[('in_preparation', 'En préparation'), ('to_process', 'À traiter'), ('in_progress', 'En cours'), ('processed', 'Traité'), ('not_relevant', 'Non relevant'), ('to_redirect', 'À rediriger'), ('duplicate', 'Doublon'), ('archived', 'Archivé')], default='in_preparation', max_length=20)),
|
||||
('status', models.CharField(choices=[('in_preparation', 'En préparation'), ('to_process', 'À traiter'), ('in_progress', 'En cours'), ('processed', 'Traité'), ('not_relevant', 'Non relevant'), ('to_redirect', 'À rediriger'), ('duplicate', 'Doublon'), ('closed', 'Clôturé'), ('archived', 'Archivé')], default='in_preparation', max_length=20)),
|
||||
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='observations', to='assets.assetcategory')),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='observations', to=settings.AUTH_USER_MODEL)),
|
||||
('intervention', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='observations', to='interventions.intervention')),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -10,7 +10,7 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
('common', '0004_initial'),
|
||||
('interventions', '0001_initial'),
|
||||
('observations', '0001_initial'),
|
||||
('projects', '0001_initial'),
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-06-07 09:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('observations', '0002_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='observation',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('in_preparation', 'En préparation'), ('to_process', 'À traiter'), ('in_progress', 'En cours'), ('processed', 'Traité'), ('not_relevant', 'Non relevant'), ('to_redirect', 'À rediriger'), ('duplicate', 'Doublon'), ('closed', 'Clôturé'), ('archived', 'Archivé')], default='in_preparation', max_length=20),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-19 05:35
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
@ -26,6 +26,8 @@ class Migration(migrations.Migration):
|
|||
('progress', models.IntegerField(default=0, verbose_name='Progression (%)')),
|
||||
('error_message', models.TextField(blank=True, null=True, verbose_name="Message d'erreur")),
|
||||
('upload_set_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='ID de session Panoramax')),
|
||||
('associated_collections', models.JSONField(blank=True, default=list, verbose_name='Collections associées')),
|
||||
('camera_offset', models.IntegerField(default=0, verbose_name="Offset d'orientation caméra (degrés)")),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Date de création')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Date de mise à jour')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Utilisateur')),
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-19 13:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('panoramax', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='panoramaxupload',
|
||||
name='associated_collections',
|
||||
field=models.JSONField(blank=True, default=list, verbose_name='Collections associées'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-07-19 13:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('panoramax', '0002_panoramaxupload_associated_collections'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='panoramaxupload',
|
||||
name='camera_offset',
|
||||
field=models.IntegerField(default=0, verbose_name="Offset d'orientation caméra (degrés)"),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
@ -13,7 +13,7 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('common', '0003_initial'),
|
||||
('common', '0004_initial'),
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('contracts', '0001_initial'),
|
||||
('documents', '0001_initial'),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.db.models.deletion
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
from django.contrib.postgres.operations import TrigramExtension
|
||||
from django.db import migrations
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('schools', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
TrigramExtension(),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-21 13:51
|
||||
# Generated by Django 6.0.7 on 2026-07-22 13:42
|
||||
|
||||
import common.storages
|
||||
import django.contrib.gis.db.models.fields
|
||||
|
|
@ -49,6 +49,9 @@ class Migration(migrations.Migration):
|
|||
('name_nl', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('sgv_picture', models.ImageField(blank=True, null=True, upload_to='sign/signpanels_types/')),
|
||||
('default_width', models.FloatField(blank=True, null=True, verbose_name='Largeur par défaut (cm)')),
|
||||
('default_height', models.FloatField(blank=True, null=True, verbose_name='Hauteur par défaut (cm)')),
|
||||
('default_diameter', models.FloatField(blank=True, null=True, verbose_name='Diamètre par défaut (cm)')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
|
|
@ -131,7 +134,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -162,6 +165,7 @@ class Migration(migrations.Migration):
|
|||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sign_app_panels', to='sign.organization')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='sign.signpanel', verbose_name='Remplacé par')),
|
||||
('street', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sign_app_panels', to='common.adrstreet')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
],
|
||||
),
|
||||
|
|
@ -246,7 +250,7 @@ class Migration(migrations.Migration):
|
|||
('code', models.CharField(max_length=50)),
|
||||
('name_fr', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('name_nl', models.CharField(blank=True, max_length=200, null=True)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé')], default='active', max_length=50)),
|
||||
('status', models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50)),
|
||||
('obsolescence', models.CharField(blank=True, choices=[('good', 'Bon état'), ('medium', 'Moyen'), ('bad', 'Dégradé'), ('critical', 'Critique'), ('unknown', 'Inconnu')], default='unknown', null=True)),
|
||||
('installation_date', models.DateTimeField(blank=True, null=True)),
|
||||
('uninstallation_date', models.DateTimeField(blank=True, null=True)),
|
||||
|
|
@ -270,6 +274,7 @@ class Migration(migrations.Migration):
|
|||
('marked_as_removed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_marked_as_removed', to=settings.AUTH_USER_MODEL, verbose_name='Marqué comme retiré par')),
|
||||
('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sign_app_poles', to='sign.organization')),
|
||||
('replaced_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='replaces', to='sign.signpole', verbose_name='Remplacé par')),
|
||||
('street', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sign_app_poles', to='common.adrstreet')),
|
||||
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(app_label)s_%(class)s_updated_by', to=settings.AUTH_USER_MODEL, verbose_name='Mis à jour par')),
|
||||
],
|
||||
),
|
||||
|
|
@ -328,16 +333,6 @@ class Migration(migrations.Migration):
|
|||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signpole',
|
||||
name='street',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='sign_app_poles', to='sign.signstreet'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='signpanel',
|
||||
name='street',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sign_app_panels', to='sign.signstreet'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SignStreetDocument',
|
||||
fields=[
|
||||
|
|
@ -370,12 +365,12 @@ class Migration(migrations.Migration):
|
|||
name='signpaneltypearticle',
|
||||
unique_together={('panel_type', 'article')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='signpole',
|
||||
index=models.Index(fields=['code'], name='sign_signpo_code_16a79b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='signpanel',
|
||||
index=models.Index(fields=['code'], name='sign_signpa_code_65ed88_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='signpole',
|
||||
index=models.Index(fields=['code'], name='sign_signpo_code_16a79b_idx'),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-23 05:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sign', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='signpanel',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signpole',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('to_be_approved', 'À approuver'), ('planned', 'Planifié'), ('active', 'Actif'), ('damaged', 'Endommagé'), ('to_replace', 'A remplacer'), ('voluntarily_out_of_service', 'Mis hors service volontairement'), ('removed', 'Enlevé'), ('archived', 'Archivé')], default='active', max_length=50),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# Generated by Django 5.2.8 on 2026-05-24 16:32
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0005_userconfig_calendar_preferences'),
|
||||
('sign', '0002_alter_signpanel_status_alter_signpole_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='signpanel',
|
||||
name='street',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sign_app_panels', to='common.adrstreet'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='signpole',
|
||||
name='street',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sign_app_poles', to='common.adrstreet'),
|
||||
),
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue