fix: initialize missing member history and handle bidirectional m2m team updates in signals
This commit is contained in:
parent
9702a19db8
commit
d131fcb0d6
2 changed files with 56 additions and 25 deletions
|
|
@ -125,6 +125,21 @@ def sync_member_current_teams(member: CompanyMember, for_date: Optional[date] =
|
||||||
if for_date is None:
|
if for_date is None:
|
||||||
for_date = timezone.now().date()
|
for_date = timezone.now().date()
|
||||||
|
|
||||||
|
has_history = CompanyMemberHistory.objects.filter(member=member).exists()
|
||||||
|
if not has_history:
|
||||||
|
# Si le membre n'a aucun historique d'assignation mais a des équipes configurées dans member.teams,
|
||||||
|
# on initialise son historique pour préserver ses affectations.
|
||||||
|
current_teams = list(member.teams.all())
|
||||||
|
if current_teams:
|
||||||
|
for t in current_teams:
|
||||||
|
CompanyMemberHistory.objects.get_or_create(
|
||||||
|
member=member,
|
||||||
|
team=t,
|
||||||
|
leave_date__isnull=True,
|
||||||
|
defaults={'join_date': for_date}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
active_team = get_member_team_for_date(member, for_date)
|
active_team = get_member_team_for_date(member, for_date)
|
||||||
current_team_ids = set(member.teams.values_list('id', flat=True))
|
current_team_ids = set(member.teams.values_list('id', flat=True))
|
||||||
target_team_ids = {active_team.id} if active_team else set()
|
target_team_ids = {active_team.id} if active_team else set()
|
||||||
|
|
|
||||||
|
|
@ -51,34 +51,50 @@ from django.utils import timezone
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=CompanyMember.teams.through)
|
@receiver(m2m_changed, sender=CompanyMember.teams.through)
|
||||||
def update_member_team_history(sender, instance, action, reverse, pk_set, **kwargs):
|
def update_member_team_history(sender, instance, action, reverse, pk_set, **kwargs):
|
||||||
if reverse:
|
|
||||||
return
|
|
||||||
|
|
||||||
today = timezone.now().date()
|
today = timezone.now().date()
|
||||||
|
|
||||||
if action == "post_add":
|
if not reverse:
|
||||||
# Pour chaque équipe ajoutée, on crée un enregistrement d'historique s'il n'existe pas déjà de période active
|
# instance est CompanyMember, pk_set contient les team_id
|
||||||
for team_id in pk_set:
|
if action == "post_add" and pk_set:
|
||||||
CompanyMemberHistory.objects.get_or_create(
|
for team_id in pk_set:
|
||||||
member=instance,
|
CompanyMemberHistory.objects.get_or_create(
|
||||||
team_id=team_id,
|
member=instance,
|
||||||
leave_date__isnull=True,
|
team_id=team_id,
|
||||||
defaults={'join_date': today}
|
leave_date__isnull=True,
|
||||||
)
|
defaults={'join_date': today}
|
||||||
|
)
|
||||||
elif action == "post_remove":
|
elif action == "post_remove" and pk_set:
|
||||||
# Pour chaque équipe retirée, on clôture la période d'appartenance active
|
for team_id in pk_set:
|
||||||
for team_id in pk_set:
|
CompanyMemberHistory.objects.filter(
|
||||||
|
member=instance,
|
||||||
|
team_id=team_id,
|
||||||
|
leave_date__isnull=True
|
||||||
|
).update(leave_date=today)
|
||||||
|
elif action == "pre_clear":
|
||||||
CompanyMemberHistory.objects.filter(
|
CompanyMemberHistory.objects.filter(
|
||||||
member=instance,
|
member=instance,
|
||||||
team_id=team_id,
|
leave_date__isnull=True
|
||||||
|
).update(leave_date=today)
|
||||||
|
else:
|
||||||
|
# instance est CompanyTeam, pk_set contient les member_id
|
||||||
|
if action == "post_add" and pk_set:
|
||||||
|
for member_id in pk_set:
|
||||||
|
CompanyMemberHistory.objects.get_or_create(
|
||||||
|
member_id=member_id,
|
||||||
|
team=instance,
|
||||||
|
leave_date__isnull=True,
|
||||||
|
defaults={'join_date': today}
|
||||||
|
)
|
||||||
|
elif action == "post_remove" and pk_set:
|
||||||
|
for member_id in pk_set:
|
||||||
|
CompanyMemberHistory.objects.filter(
|
||||||
|
member_id=member_id,
|
||||||
|
team=instance,
|
||||||
|
leave_date__isnull=True
|
||||||
|
).update(leave_date=today)
|
||||||
|
elif action == "pre_clear":
|
||||||
|
CompanyMemberHistory.objects.filter(
|
||||||
|
team=instance,
|
||||||
leave_date__isnull=True
|
leave_date__isnull=True
|
||||||
).update(leave_date=today)
|
).update(leave_date=today)
|
||||||
|
|
||||||
elif action == "pre_clear":
|
|
||||||
# Avant d'effacer toutes les équipes d'un membre, on clôture toutes les périodes actives
|
|
||||||
CompanyMemberHistory.objects.filter(
|
|
||||||
member=instance,
|
|
||||||
leave_date__isnull=True
|
|
||||||
).update(leave_date=today)
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue