refactor: optimize intervention assignment logic and enforce strict deduplication by ID
This commit is contained in:
parent
32053f3635
commit
0a745be17c
1 changed files with 34 additions and 36 deletions
|
|
@ -1506,19 +1506,7 @@ def member_history_ajax(request, member_id):
|
|||
)
|
||||
company_str = ", ".join(sorted(company_names)) if company_names else '—'
|
||||
|
||||
# Filter assignments:
|
||||
# 1. Directly assigned to this member in InterventionAssignment
|
||||
assignment_q = Q(member=member)
|
||||
|
||||
# 2. Directly assigned / acted upon by member user on Intervention
|
||||
if member.user_id:
|
||||
assignment_q |= (
|
||||
Q(intervention__assigned_member=member) |
|
||||
Q(intervention__realized_events__event_user=member.user) |
|
||||
Q(intervention__occupations__member=member)
|
||||
)
|
||||
|
||||
# 3. Interventions assigned to teams during the periods member was in that team
|
||||
# 1. Équipes et périodes valides du membre selon CompanyMemberHistory
|
||||
team_periods_q = Q()
|
||||
for h in team_history_qs:
|
||||
if h.team_id and h.join_date:
|
||||
|
|
@ -1527,10 +1515,8 @@ def member_history_ajax(request, member_id):
|
|||
tq &= Q(date__lte=h.leave_date)
|
||||
team_periods_q |= tq
|
||||
|
||||
for t in member.teams.all():
|
||||
if not team_history_qs.filter(team=t).exists():
|
||||
team_periods_q |= Q(team=t)
|
||||
|
||||
# 2. Récupérer les affectations d'interventions liées au membre
|
||||
assignment_q = Q(member=member)
|
||||
if team_periods_q:
|
||||
assignment_q |= team_periods_q
|
||||
|
||||
|
|
@ -1538,26 +1524,31 @@ def member_history_ajax(request, member_id):
|
|||
InterventionAssignment.objects
|
||||
.filter(assignment_q)
|
||||
.select_related('intervention', 'team')
|
||||
.order_by('-date', '-intervention__code', '-intervention__id')[:100]
|
||||
.order_by('-date', '-intervention__id')
|
||||
)
|
||||
|
||||
interventions_list = [
|
||||
{
|
||||
'id': a.intervention.id,
|
||||
'code': a.intervention.code,
|
||||
'title': a.intervention.title,
|
||||
# 3. Dédoublonnage strict par ID d'intervention
|
||||
seen_itv_ids = set()
|
||||
interventions_dict = {}
|
||||
|
||||
for a in assignments_qs:
|
||||
itv = a.intervention
|
||||
if not itv or itv.id in seen_itv_ids:
|
||||
continue
|
||||
seen_itv_ids.add(itv.id)
|
||||
interventions_dict[itv.id] = {
|
||||
'id': itv.id,
|
||||
'code': itv.code,
|
||||
'title': itv.title,
|
||||
'date': a.date.strftime('%d/%m/%Y') if a.date else '',
|
||||
'raw_date': a.date.isoformat() if a.date else '',
|
||||
'team_name': a.team.name if a.team else (a.intervention.assigned_team.name if a.intervention.assigned_team else '—'),
|
||||
'status_code': a.intervention.status,
|
||||
'status_display': a.intervention.get_status_display(),
|
||||
'detail_url': reverse('interventions:intervention_detail', args=[a.intervention.id]),
|
||||
'team_name': a.team.name if a.team else (itv.assigned_team.name if itv.assigned_team else '—'),
|
||||
'status_code': itv.status,
|
||||
'status_display': itv.get_status_display(),
|
||||
'detail_url': reverse('interventions:intervention_detail', args=[itv.id]),
|
||||
}
|
||||
for a in assignments_qs
|
||||
]
|
||||
|
||||
# Include any extra interventions directly assigned/realized by member without an InterventionAssignment
|
||||
assigned_itv_ids = set(a.intervention.id for a in assignments_qs)
|
||||
# 4. Interventions directement assignées ou réalisées personnellement par le membre
|
||||
direct_itvs_q = Q(assigned_member=member)
|
||||
if member.user_id:
|
||||
direct_itvs_q |= Q(realized_events__event_user=member.user) | Q(occupations__member=member)
|
||||
|
|
@ -1565,10 +1556,16 @@ def member_history_ajax(request, member_id):
|
|||
extra_itvs = (
|
||||
Intervention.objects
|
||||
.filter(direct_itvs_q)
|
||||
.exclude(id__in=assigned_itv_ids)
|
||||
.select_related('assigned_team')[:50]
|
||||
.exclude(id__in=seen_itv_ids)
|
||||
.select_related('assigned_team')
|
||||
.distinct()[:50]
|
||||
)
|
||||
|
||||
for itv in extra_itvs:
|
||||
if itv.id in seen_itv_ids:
|
||||
continue
|
||||
seen_itv_ids.add(itv.id)
|
||||
|
||||
itv_date = (itv.end_time or itv.begin_time or itv.planned_begin_time or itv.creation_time)
|
||||
if itv_date:
|
||||
itv_date_local = timezone.localtime(itv_date) if timezone.is_aware(itv_date) else itv_date
|
||||
|
|
@ -1578,7 +1575,7 @@ def member_history_ajax(request, member_id):
|
|||
date_str = ''
|
||||
raw_date_str = ''
|
||||
|
||||
interventions_list.append({
|
||||
interventions_dict[itv.id] = {
|
||||
'id': itv.id,
|
||||
'code': itv.code,
|
||||
'title': itv.title,
|
||||
|
|
@ -1588,10 +1585,11 @@ def member_history_ajax(request, member_id):
|
|||
'status_code': itv.status,
|
||||
'status_display': itv.get_status_display(),
|
||||
'detail_url': reverse('interventions:intervention_detail', args=[itv.id]),
|
||||
})
|
||||
}
|
||||
|
||||
interventions_list = list(interventions_dict.values())
|
||||
interventions_list.sort(key=lambda x: (x['raw_date'], x['code'] or '', x['id']), reverse=True)
|
||||
interventions_list = interventions_list[:100]
|
||||
interventions_list = interventions_list[:50]
|
||||
|
||||
return JsonResponse({
|
||||
'member': {
|
||||
|
|
|
|||
Loading…
Reference in a new issue