82 lines
3.6 KiB
Python
82 lines
3.6 KiB
Python
from django.core.management.base import BaseCommand
|
||
from django.utils import timezone
|
||
from datetime import timedelta
|
||
from interventions.models import Intervention, InterventionTimeLine, InterventionNote, SymptomContractAutoClose
|
||
|
||
class Command(BaseCommand):
|
||
help = "Clôture automatique des interventions selon les règles (symptôme × contrat)"
|
||
|
||
def handle(self, *args, **options):
|
||
self.stdout.write("=== Démarrage de la clôture automatique des interventions ===")
|
||
now = timezone.now()
|
||
|
||
# Statuts éligibles pour la clôture
|
||
eligible_statuses = ['to_be_processed', 'assigned', 'processed', 'finished']
|
||
|
||
# Charger toutes les règles actives (contrat actif)
|
||
rules = SymptomContractAutoClose.objects.filter(
|
||
contract__is_active=True,
|
||
).select_related('symptom', 'contract')
|
||
|
||
if not rules.exists():
|
||
self.stdout.write("Aucune règle de clôture automatique configurée.")
|
||
self.stdout.write("=== Fin de la clôture automatique des interventions ===")
|
||
return
|
||
|
||
closed_count = 0
|
||
|
||
for rule in rules:
|
||
interventions = Intervention.objects.filter(
|
||
status__in=eligible_statuses,
|
||
symptom=rule.symptom,
|
||
contract=rule.contract,
|
||
).select_related('contract', 'symptom')
|
||
|
||
for itv in interventions:
|
||
# Récupérer la date de référence (dernier passage dans le statut actuel)
|
||
timeline_event = InterventionTimeLine.objects.filter(
|
||
intervention=itv,
|
||
to_status=itv.status,
|
||
).order_by('-event_time').first()
|
||
|
||
if timeline_event:
|
||
completion_date = timeline_event.event_time
|
||
elif itv.end_time:
|
||
completion_date = itv.end_time
|
||
elif itv.last_modified_time:
|
||
completion_date = itv.last_modified_time
|
||
else:
|
||
completion_date = itv.creation_time
|
||
|
||
if now - completion_date >= timedelta(days=rule.delay_days):
|
||
old_status = itv.status
|
||
itv.status = 'closed'
|
||
itv.save()
|
||
|
||
InterventionTimeLine.objects.create(
|
||
intervention=itv,
|
||
event_time=now,
|
||
event_type='status_change',
|
||
from_status=old_status,
|
||
to_status='closed',
|
||
)
|
||
|
||
InterventionNote.objects.create(
|
||
intervention=itv,
|
||
note_time=now,
|
||
note_type=InterventionNote.NoteType.IMPORTANT_INFO,
|
||
content=(
|
||
f"Clôture automatique après {rule.delay_days} jour(s) "
|
||
f"(règle : {rule.symptom.code or rule.symptom.get_name()} × {rule.contract.contract_number})."
|
||
),
|
||
)
|
||
|
||
closed_count += 1
|
||
ref_source = f"Règle {rule.symptom.code or rule.symptom.id} × {rule.contract.contract_number}"
|
||
self.stdout.write(self.style.SUCCESS(
|
||
f" -> Intervention {itv.code} clôturée (via {ref_source}, délai : {rule.delay_days}j, "
|
||
f"statut précédent : {old_status}, date référence : {completion_date.strftime('%d/%m/%Y %H:%M')})"
|
||
))
|
||
|
||
self.stdout.write(f"Total : {closed_count} intervention(s) clôturée(s).")
|
||
self.stdout.write("=== Fin de la clôture automatique des interventions ===")
|