refactor: support multiple intervention types in subtypes and update non-compliance notifications for company members
This commit is contained in:
parent
7ca27197bf
commit
396d26414c
8 changed files with 231 additions and 35 deletions
|
|
@ -304,7 +304,19 @@ class Inspection(models.Model):
|
||||||
if not teams:
|
if not teams:
|
||||||
return
|
return
|
||||||
|
|
||||||
from notifications.services import notify_team
|
from contracts.models import CompanyMember
|
||||||
|
from notifications.models import Notification, NotificationRecipient
|
||||||
|
from notifications.webpush import send_webpush_to_users
|
||||||
|
|
||||||
|
# Collecter tous les membres actifs avec un compte utilisateur
|
||||||
|
recipient_user_ids = set(
|
||||||
|
CompanyMember.objects.filter(
|
||||||
|
teams__in=teams, user__isnull=False, user__is_active=True
|
||||||
|
).values_list('user_id', flat=True)
|
||||||
|
)
|
||||||
|
if not recipient_user_ids:
|
||||||
|
return
|
||||||
|
|
||||||
status_label = self.get_result_status_display()
|
status_label = self.get_result_status_display()
|
||||||
title = _("Non-conformité durabilité (%(status)s) : %(code)s") % {
|
title = _("Non-conformité durabilité (%(status)s) : %(code)s") % {
|
||||||
'status': status_label,
|
'status': status_label,
|
||||||
|
|
@ -325,21 +337,31 @@ class Inspection(models.Model):
|
||||||
}
|
}
|
||||||
action_url = f"/interventions/{self.checked_intervention.id}/"
|
action_url = f"/interventions/{self.checked_intervention.id}/"
|
||||||
|
|
||||||
for team in teams:
|
|
||||||
try:
|
try:
|
||||||
notify_team(
|
notification = Notification.objects.create(
|
||||||
team=team,
|
|
||||||
title=str(title),
|
title=str(title),
|
||||||
content=str(content),
|
content=str(content),
|
||||||
notification_type='alert',
|
notification_type='alert',
|
||||||
action_url=action_url,
|
action_url=action_url,
|
||||||
action_label=str(_("Consulter l'intervention")),
|
action_label=str(_("Consulter l'intervention")),
|
||||||
source_app='inspections',
|
source_app='inspections',
|
||||||
|
is_system=True,
|
||||||
|
)
|
||||||
|
NotificationRecipient.objects.bulk_create([
|
||||||
|
NotificationRecipient(notification=notification, user_id=uid)
|
||||||
|
for uid in recipient_user_ids
|
||||||
|
], ignore_conflicts=True)
|
||||||
|
|
||||||
|
send_webpush_to_users(
|
||||||
|
users=list(recipient_user_ids),
|
||||||
|
title=str(title),
|
||||||
|
body=str(content),
|
||||||
|
action_url=action_url,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
import logging
|
import logging
|
||||||
logging.getLogger(__name__).exception(
|
logging.getLogger(__name__).exception(
|
||||||
f"Error sending non-compliance notification for inspection {self.pk} to team {team.pk}"
|
f"Error sending non-compliance notification for inspection {self.pk}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.non_compliance_notified = True
|
self.non_compliance_notified = True
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,12 @@ def schedule_post_intervention_inspection(intervention):
|
||||||
|
|
||||||
# 2. Résolution administrative par commune associée
|
# 2. Résolution administrative par commune associée
|
||||||
if not zone:
|
if not zone:
|
||||||
|
from common.models import Municipality
|
||||||
for loc in intervention.locations.all():
|
for loc in intervention.locations.all():
|
||||||
loc_obj = loc.location
|
loc_obj = loc.location
|
||||||
if loc_obj and hasattr(loc_obj, 'municipality') and loc_obj.municipality:
|
muni_to_check = loc_obj if isinstance(loc_obj, Municipality) else getattr(loc_obj, 'municipality', None)
|
||||||
zone = zones.filter(municipalities=loc_obj.municipality).first()
|
if muni_to_check:
|
||||||
|
zone = zones.filter(municipalities=muni_to_check).first()
|
||||||
if zone:
|
if zone:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1507,9 +1507,11 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
can_inspect=True
|
can_inspect=True
|
||||||
)
|
)
|
||||||
|
|
||||||
from notifications.models import Team
|
from contracts.models import Company, CompanyTeam, CompanyMember
|
||||||
self.team = Team.objects.create(name='Équipe Contrôle Enrobés')
|
self.company = Company.objects.create(name='Test Company Asphalt')
|
||||||
self.team.members.add(self.user)
|
self.team = CompanyTeam.objects.create(name='Équipe Contrôle Enrobés', company=self.company)
|
||||||
|
self.member = CompanyMember.objects.create(name='Test Inspector', user=self.user)
|
||||||
|
self.member.teams.add(self.team)
|
||||||
|
|
||||||
from interventions.models import InterventionSubType
|
from interventions.models import InterventionSubType
|
||||||
self.hotbox_subtype = InterventionSubType.objects.create(
|
self.hotbox_subtype = InterventionSubType.objects.create(
|
||||||
|
|
@ -1517,7 +1519,7 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
name_fr='Hot Box (asphalte à chaud)',
|
name_fr='Hot Box (asphalte à chaud)',
|
||||||
name_nl='Hot Box (warm asfalt)',
|
name_nl='Hot Box (warm asfalt)',
|
||||||
thematic=self.roads_thematic,
|
thematic=self.roads_thematic,
|
||||||
intervention_type='repair',
|
intervention_types=['repair'],
|
||||||
requires_post_inspection=True,
|
requires_post_inspection=True,
|
||||||
post_inspection_delay_min_days=30,
|
post_inspection_delay_min_days=30,
|
||||||
post_inspection_delay_max_days=60,
|
post_inspection_delay_max_days=60,
|
||||||
|
|
@ -1529,7 +1531,7 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
code='test_roads_repair_standard',
|
code='test_roads_repair_standard',
|
||||||
name_fr='Réparation standard',
|
name_fr='Réparation standard',
|
||||||
thematic=self.roads_thematic,
|
thematic=self.roads_thematic,
|
||||||
intervention_type='repair',
|
intervention_types=['repair'],
|
||||||
requires_post_inspection=False
|
requires_post_inspection=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1570,7 +1572,7 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
thematic=self.roads_thematic
|
thematic=self.roads_thematic
|
||||||
)
|
)
|
||||||
zone.inspectors.add(self.user)
|
zone.inspectors.add(self.user)
|
||||||
muni = Municipality.objects.create(name_fr='Schaerbeek Test', code='21099')
|
muni = Municipality.objects.create(name_fr='Schaerbeek Test', name_nl='Schaarbeek Test', niscode='21099', fid='21099')
|
||||||
zone.municipalities.add(muni)
|
zone.municipalities.add(muni)
|
||||||
|
|
||||||
intervention = Intervention.objects.create(
|
intervention = Intervention.objects.create(
|
||||||
|
|
@ -1596,7 +1598,7 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
self.assertTrue(insp.can_edit(self.user))
|
self.assertTrue(insp.can_edit(self.user))
|
||||||
|
|
||||||
def test_non_compliance_triggers_team_notification(self):
|
def test_non_compliance_triggers_team_notification(self):
|
||||||
from notifications.models import TeamNotificationTarget
|
from notifications.models import NotificationRecipient
|
||||||
intervention = Intervention.objects.create(
|
intervention = Intervention.objects.create(
|
||||||
thematic=self.roads_thematic,
|
thematic=self.roads_thematic,
|
||||||
type='repair',
|
type='repair',
|
||||||
|
|
@ -1615,7 +1617,7 @@ class PostInterventionDurabilityInspectionTestCase(TestCase):
|
||||||
|
|
||||||
insp.refresh_from_db()
|
insp.refresh_from_db()
|
||||||
self.assertTrue(insp.non_compliance_notified)
|
self.assertTrue(insp.non_compliance_notified)
|
||||||
self.assertTrue(TeamNotificationTarget.objects.filter(team=self.team).exists())
|
self.assertTrue(NotificationRecipient.objects.filter(user=self.user, notification__source_app='inspections').exists())
|
||||||
|
|
||||||
def test_subtype_without_post_inspection_does_not_trigger(self):
|
def test_subtype_without_post_inspection_does_not_trigger(self):
|
||||||
intervention = Intervention.objects.create(
|
intervention = Intervention.objects.create(
|
||||||
|
|
|
||||||
|
|
@ -42,20 +42,42 @@ from .services import generate_interventions_excel
|
||||||
from common.models import Thematic
|
from common.models import Thematic
|
||||||
from assets.models import AssetCategory
|
from assets.models import AssetCategory
|
||||||
from interventions.views.preventive_import import process_worksheet as _process_worksheet
|
from interventions.views.preventive_import import process_worksheet as _process_worksheet
|
||||||
from interventions.models import STATUS_CHOICES, DirectContractRouting
|
from interventions.models import STATUS_CHOICES, DirectContractRouting, TYPE_CHOICES
|
||||||
|
|
||||||
|
|
||||||
|
class InterventionSubTypeAdminForm(forms.ModelForm):
|
||||||
|
intervention_types = forms.MultipleChoiceField(
|
||||||
|
choices=TYPE_CHOICES,
|
||||||
|
required=False,
|
||||||
|
widget=FilteredSelectMultiple(_("Types d'intervention"), is_stacked=False),
|
||||||
|
label=_("Types d'intervention"),
|
||||||
|
help_text=_("Types d'intervention auxquels ce sous-type s'applique. Si aucun n'est sélectionné, s'applique à tous les types."),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = InterventionSubType
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
@admin.register(InterventionSubType)
|
@admin.register(InterventionSubType)
|
||||||
class InterventionSubTypeAdmin(admin.ModelAdmin):
|
class InterventionSubTypeAdmin(admin.ModelAdmin):
|
||||||
|
form = InterventionSubTypeAdminForm
|
||||||
list_display = (
|
list_display = (
|
||||||
"code", "name_fr", "thematic", "intervention_type",
|
"code", "name_fr", "thematic", "types_display",
|
||||||
"requires_post_inspection", "post_inspection_delay_min_days",
|
"requires_post_inspection", "post_inspection_delay_min_days",
|
||||||
"post_inspection_delay_max_days", "is_active"
|
"post_inspection_delay_max_days", "is_active"
|
||||||
)
|
)
|
||||||
list_filter = ("thematic", "intervention_type", "requires_post_inspection", "is_active")
|
list_filter = ("thematic", "requires_post_inspection", "is_active")
|
||||||
search_fields = ("code", "name_fr", "name_nl")
|
search_fields = ("code", "name_fr", "name_nl")
|
||||||
filter_horizontal = ("notification_teams",)
|
filter_horizontal = ("notification_teams",)
|
||||||
|
|
||||||
|
def types_display(self, obj):
|
||||||
|
if not obj.intervention_types:
|
||||||
|
return _("Tous")
|
||||||
|
type_dict = dict(TYPE_CHOICES)
|
||||||
|
return ", ".join(str(type_dict.get(t, t)) for t in obj.intervention_types)
|
||||||
|
types_display.short_description = _("Types d'intervention")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Intervention)
|
@admin.register(Intervention)
|
||||||
class InterventionAdmin(admin.ModelAdmin):
|
class InterventionAdmin(admin.ModelAdmin):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Generated by Django 6.0.7 on 2026-09-17 13:59
|
||||||
|
|
||||||
|
import django.contrib.postgres.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_single_type_to_multiple(apps, schema_editor):
|
||||||
|
InterventionSubType = apps.get_model('interventions', 'InterventionSubType')
|
||||||
|
for subtype in InterventionSubType.objects.all():
|
||||||
|
old_val = getattr(subtype, 'intervention_type', None)
|
||||||
|
if old_val:
|
||||||
|
subtype.intervention_types = [old_val]
|
||||||
|
subtype.save(update_fields=['intervention_types'])
|
||||||
|
elif subtype.code == 'roads_repair_hotbox':
|
||||||
|
subtype.intervention_types = ['repair']
|
||||||
|
subtype.save(update_fields=['intervention_types'])
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_multiple_to_single(apps, schema_editor):
|
||||||
|
InterventionSubType = apps.get_model('interventions', 'InterventionSubType')
|
||||||
|
for subtype in InterventionSubType.objects.all():
|
||||||
|
if subtype.intervention_types:
|
||||||
|
subtype.intervention_type = subtype.intervention_types[0]
|
||||||
|
subtype.save(update_fields=['intervention_type'])
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contracts', '0007_contract_approval_except_urgent'),
|
||||||
|
('interventions', '0010_seed_roads_hotbox_subtype'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='interventionsubtype',
|
||||||
|
options={'ordering': ['thematic', 'order_number', 'name_fr'], 'verbose_name': "Sous-type d'intervention", 'verbose_name_plural': "Sous-types d'interventions"},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='interventionsubtype',
|
||||||
|
name='intervention_types',
|
||||||
|
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(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'), ('reprogramming', 'Reprogrammation')], max_length=50), blank=True, default=list, help_text="Types d'intervention auxquels ce sous-type s'applique. Laisser vide pour s'appliquer à tous les types.", verbose_name="Types d'intervention"),
|
||||||
|
),
|
||||||
|
migrations.RunPython(migrate_single_type_to_multiple, reverse_code=reverse_multiple_to_single),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='interventionsubtype',
|
||||||
|
name='intervention_type',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interventionsubtype',
|
||||||
|
name='notification_teams',
|
||||||
|
field=models.ManyToManyField(blank=True, help_text="Équipes notifiées si l'inspection de durabilité révèle un constat non-conforme.", related_name='intervention_subtypes', to='contracts.companyteam', verbose_name='Équipes à notifier'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -5,6 +5,7 @@ from django.conf import settings
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import get_language, gettext_lazy as _
|
from django.utils.translation import get_language, gettext_lazy as _
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from django.db.models import Sum, F, Q
|
from django.db.models import Sum, F, Q
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
|
|
||||||
|
|
@ -201,7 +202,13 @@ class InterventionSubType(models.Model):
|
||||||
name_fr = models.CharField(max_length=200, verbose_name=_("Nom (FR)"))
|
name_fr = models.CharField(max_length=200, verbose_name=_("Nom (FR)"))
|
||||||
name_nl = models.CharField(max_length=200, blank=True, verbose_name=_("Nom (NL)"))
|
name_nl = models.CharField(max_length=200, blank=True, verbose_name=_("Nom (NL)"))
|
||||||
thematic = models.ForeignKey(Thematic, on_delete=models.PROTECT, related_name='intervention_subtypes', verbose_name=_("Thématique"))
|
thematic = models.ForeignKey(Thematic, on_delete=models.PROTECT, related_name='intervention_subtypes', verbose_name=_("Thématique"))
|
||||||
intervention_type = models.CharField(max_length=50, choices=TYPE_CHOICES, verbose_name=_("Type d'intervention"))
|
intervention_types = ArrayField(
|
||||||
|
models.CharField(max_length=50, choices=TYPE_CHOICES),
|
||||||
|
default=list,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("Types d'intervention"),
|
||||||
|
help_text=_("Types d'intervention auxquels ce sous-type s'applique. Laisser vide pour s'appliquer à tous les types.")
|
||||||
|
)
|
||||||
|
|
||||||
# Paramètres de durabilité / inspection post-travaux
|
# Paramètres de durabilité / inspection post-travaux
|
||||||
requires_post_inspection = models.BooleanField(
|
requires_post_inspection = models.BooleanField(
|
||||||
|
|
@ -226,7 +233,7 @@ class InterventionSubType(models.Model):
|
||||||
verbose_name=_("Nature de l'inspection")
|
verbose_name=_("Nature de l'inspection")
|
||||||
)
|
)
|
||||||
notification_teams = models.ManyToManyField(
|
notification_teams = models.ManyToManyField(
|
||||||
'notifications.Team',
|
CompanyTeam,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name='intervention_subtypes',
|
related_name='intervention_subtypes',
|
||||||
verbose_name=_("Équipes à notifier"),
|
verbose_name=_("Équipes à notifier"),
|
||||||
|
|
@ -238,7 +245,7 @@ class InterventionSubType(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Sous-type d'intervention")
|
verbose_name = _("Sous-type d'intervention")
|
||||||
verbose_name_plural = _("Sous-types d'interventions")
|
verbose_name_plural = _("Sous-types d'interventions")
|
||||||
ordering = ['thematic', 'intervention_type', 'order_number', 'name_fr']
|
ordering = ['thematic', 'order_number', 'name_fr']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.get_name()} ({self.thematic.name})"
|
return f"{self.get_name()} ({self.thematic.name})"
|
||||||
|
|
|
||||||
|
|
@ -566,5 +566,86 @@ class InspectionTests(TestCase):
|
||||||
self.assertIn('member_assignment', allowed_fields)
|
self.assertIn('member_assignment', allowed_fields)
|
||||||
|
|
||||||
|
|
||||||
|
class InterventionSubTypeTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
User = get_user_model()
|
||||||
|
self.user = User.objects.create_user(username='subtype_test_user', password='pwd')
|
||||||
|
self.thematic = Thematic.objects.create(code='roads_test', name_fr='Voirie Test', name_nl='Wegen Test')
|
||||||
|
self.company = Company.objects.create(name='Test Contractor')
|
||||||
|
self.team1 = CompanyTeam.objects.create(name='Équipe Régie 1', company=self.company)
|
||||||
|
self.team2 = CompanyTeam.objects.create(name='Équipe Prestataire 2', company=self.company)
|
||||||
|
|
||||||
|
from interventions.models import InterventionSubType
|
||||||
|
self.subtype_multi = InterventionSubType.objects.create(
|
||||||
|
code='sub_multi',
|
||||||
|
name_fr='Hot Box Multi',
|
||||||
|
name_nl='Hot Box NL',
|
||||||
|
thematic=self.thematic,
|
||||||
|
intervention_types=['repair', 'fixing'],
|
||||||
|
requires_post_inspection=True,
|
||||||
|
order_number=1,
|
||||||
|
is_active=True,
|
||||||
|
)
|
||||||
|
self.subtype_multi.notification_teams.add(self.team1, self.team2)
|
||||||
|
|
||||||
|
self.subtype_universal = InterventionSubType.objects.create(
|
||||||
|
code='sub_univ',
|
||||||
|
name_fr='Universel',
|
||||||
|
name_nl='Universeel',
|
||||||
|
thematic=self.thematic,
|
||||||
|
intervention_types=[],
|
||||||
|
requires_post_inspection=False,
|
||||||
|
order_number=2,
|
||||||
|
is_active=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.subtype_build_only = InterventionSubType.objects.create(
|
||||||
|
code='sub_build',
|
||||||
|
name_fr='Construction Seule',
|
||||||
|
thematic=self.thematic,
|
||||||
|
intervention_types=['build'],
|
||||||
|
order_number=3,
|
||||||
|
is_active=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_subtype_multiple_types_and_teams(self):
|
||||||
|
from interventions.models import InterventionSubType
|
||||||
|
st = InterventionSubType.objects.get(code='sub_multi')
|
||||||
|
self.assertEqual(st.intervention_types, ['repair', 'fixing'])
|
||||||
|
self.assertEqual(st.notification_teams.count(), 2)
|
||||||
|
self.assertIn(self.team1, st.notification_teams.all())
|
||||||
|
self.assertIn(self.team2, st.notification_teams.all())
|
||||||
|
|
||||||
|
def test_form_filters_subtypes_by_type(self):
|
||||||
|
from interventions.views.forms import InterventionForm
|
||||||
|
# Form for 'repair' should include sub_multi and sub_univ, but NOT sub_build
|
||||||
|
form_repair = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'repair'})
|
||||||
|
qs_repair = form_repair.fields['sub_type'].queryset
|
||||||
|
self.assertIn(self.subtype_multi, qs_repair)
|
||||||
|
self.assertIn(self.subtype_universal, qs_repair)
|
||||||
|
self.assertNotIn(self.subtype_build_only, qs_repair)
|
||||||
|
|
||||||
|
# Form for 'build' should include sub_build and sub_univ, but NOT sub_multi
|
||||||
|
form_build = InterventionForm(thematic=self.thematic, user=self.user, initial={'type': 'build'})
|
||||||
|
qs_build = form_build.fields['sub_type'].queryset
|
||||||
|
self.assertIn(self.subtype_build_only, qs_build)
|
||||||
|
self.assertIn(self.subtype_universal, qs_build)
|
||||||
|
self.assertNotIn(self.subtype_multi, qs_build)
|
||||||
|
|
||||||
|
def test_admin_types_display(self):
|
||||||
|
from interventions.admin import InterventionSubTypeAdmin
|
||||||
|
from django.contrib.admin.sites import AdminSite
|
||||||
|
from django.utils import translation
|
||||||
|
admin_instance = InterventionSubTypeAdmin(self.subtype_multi.__class__, AdminSite())
|
||||||
|
with translation.override('fr'):
|
||||||
|
display_text = admin_instance.types_display(self.subtype_multi)
|
||||||
|
self.assertIn("Réparation", display_text)
|
||||||
|
self.assertIn("Dépannage", display_text)
|
||||||
|
|
||||||
|
display_univ = admin_instance.types_display(self.subtype_universal)
|
||||||
|
self.assertEqual(str(display_univ), "Tous")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,16 +98,22 @@ class InterventionForm(forms.ModelForm):
|
||||||
if 'type' in self.fields:
|
if 'type' in self.fields:
|
||||||
self.fields['type'].choices = get_type_choices(thematic_obj)
|
self.fields['type'].choices = get_type_choices(thematic_obj)
|
||||||
|
|
||||||
|
type_value = self.initial.get('type') or self.data.get('type') or (getattr(self.instance, 'type', None) if self.instance else None)
|
||||||
|
maintain_type_value = self.initial.get('maintain_type') or self.data.get('maintain_type') or (getattr(self.instance, 'maintain_type', None) if self.instance else None)
|
||||||
|
|
||||||
if 'sub_type' in self.fields:
|
if 'sub_type' in self.fields:
|
||||||
from interventions.models import InterventionSubType
|
from interventions.models import InterventionSubType
|
||||||
sub_type_qs = InterventionSubType.objects.filter(is_active=True)
|
sub_type_qs = InterventionSubType.objects.filter(is_active=True)
|
||||||
if thematic_obj:
|
if thematic_obj:
|
||||||
sub_type_qs = sub_type_qs.filter(thematic=thematic_obj)
|
sub_type_qs = sub_type_qs.filter(thematic=thematic_obj)
|
||||||
|
if type_value:
|
||||||
|
from django.db.models import Q
|
||||||
|
sub_type_qs = sub_type_qs.filter(
|
||||||
|
Q(intervention_types__contains=[type_value]) | Q(intervention_types=[])
|
||||||
|
)
|
||||||
self.fields['sub_type'].queryset = sub_type_qs
|
self.fields['sub_type'].queryset = sub_type_qs
|
||||||
self.fields['sub_type'].required = False
|
self.fields['sub_type'].required = False
|
||||||
|
|
||||||
type_value = self.initial.get('type') or self.data.get('type')
|
|
||||||
maintain_type_value = self.initial.get('maintain_type') or self.data.get('maintain_type')
|
|
||||||
if type_value == 'inspection':
|
if type_value == 'inspection':
|
||||||
if not self.initial.get('status') and not self.data.get('status'):
|
if not self.initial.get('status') and not self.data.get('status'):
|
||||||
self.fields['status'].initial = 'to_be_processed'
|
self.fields['status'].initial = 'to_be_processed'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue