fix: allow direct deletion of future team assignments and remove redundant confirmation dialog
This commit is contained in:
parent
71b445797d
commit
efdafa43de
3 changed files with 65 additions and 4 deletions
|
|
@ -94,8 +94,12 @@ def set_member_team_schedule(
|
||||||
# 2. Clôturer ou ajuster l'historique courant (actif à target_date)
|
# 2. Clôturer ou ajuster l'historique courant (actif à target_date)
|
||||||
if current_at_target:
|
if current_at_target:
|
||||||
if current_at_target.join_date == target_date:
|
if current_at_target.join_date == target_date:
|
||||||
current_at_target.leave_date = target_date
|
if target_date > today or team_id is None:
|
||||||
current_at_target.save(update_fields=['leave_date'])
|
# Sur une date future ou lors d'une désassignation, on supprime directement l'affectation du jour
|
||||||
|
current_at_target.delete()
|
||||||
|
else:
|
||||||
|
current_at_target.leave_date = target_date
|
||||||
|
current_at_target.save(update_fields=['leave_date'])
|
||||||
else:
|
else:
|
||||||
# L'historique commençait avant target_date : on le clôture la veille
|
# L'historique commençait avant target_date : on le clôture la veille
|
||||||
prev_leave = target_date - timedelta(days=1)
|
prev_leave = target_date - timedelta(days=1)
|
||||||
|
|
|
||||||
|
|
@ -1718,8 +1718,6 @@ function filterSidebarMembers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function unassignMemberFromDate(memberId, dateStr) {
|
function unassignMemberFromDate(memberId, dateStr) {
|
||||||
if (!confirm("{% trans 'Désassigner ce membre à partir de cette date ?'|escapejs %}")) return;
|
|
||||||
|
|
||||||
postJSON(
|
postJSON(
|
||||||
'/contracts/teams/planning/assign/',
|
'/contracts/teams/planning/assign/',
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -264,3 +264,62 @@ class TeamPlanningAjaxViewsTests(TestCase):
|
||||||
self.assertEqual(resp_dup.status_code, 400)
|
self.assertEqual(resp_dup.status_code, 400)
|
||||||
self.assertIn('passé', resp_dup.json().get('error', '').lower())
|
self.assertIn('passé', resp_dup.json().get('error', '').lower())
|
||||||
|
|
||||||
|
def test_reassign_future_member_to_same_team_as_previous_day(self):
|
||||||
|
"""
|
||||||
|
Vérifie qu'un membre présent dans Team 1 le vendredi (J) et Team 2 le samedi (J+1)
|
||||||
|
peut être replanifié dans Team 1 le samedi (J+1).
|
||||||
|
"""
|
||||||
|
today = timezone.now().date()
|
||||||
|
friday = today + timedelta(days=2)
|
||||||
|
saturday = today + timedelta(days=3)
|
||||||
|
|
||||||
|
# 1. Vendredi dans Team A, Samedi dans Team B
|
||||||
|
set_member_team_schedule(self.member_alice, self.team_a.id, friday)
|
||||||
|
set_member_team_schedule(self.member_alice, self.team_b.id, saturday)
|
||||||
|
|
||||||
|
comp1 = get_teams_composition_for_period({self.team_a.id, self.team_b.id}, friday, saturday)
|
||||||
|
self.assertIn(self.member_alice.id, [m['id'] for m in comp1.get((self.team_a.id, friday), [])])
|
||||||
|
self.assertIn(self.member_alice.id, [m['id'] for m in comp1.get((self.team_b.id, saturday), [])])
|
||||||
|
|
||||||
|
# 2. Replanifier Alice dans Team A le samedi via AJAX
|
||||||
|
url = reverse('contracts:team_planning_assign_member_ajax')
|
||||||
|
resp = self.client.post(url, data=json.dumps({
|
||||||
|
'member_id': self.member_alice.id,
|
||||||
|
'team_id': self.team_a.id,
|
||||||
|
'date': saturday.isoformat(),
|
||||||
|
}), content_type='application/json')
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
|
||||||
|
# 3. Vérifier la composition : Alice est dans Team A le vendredi ET le samedi
|
||||||
|
comp2 = get_teams_composition_for_period({self.team_a.id, self.team_b.id}, friday, saturday)
|
||||||
|
team_a_friday = [m['id'] for m in comp2.get((self.team_a.id, friday), [])]
|
||||||
|
team_a_saturday = [m['id'] for m in comp2.get((self.team_a.id, saturday), [])]
|
||||||
|
team_b_saturday = [m['id'] for m in comp2.get((self.team_b.id, saturday), [])]
|
||||||
|
|
||||||
|
self.assertIn(self.member_alice.id, team_a_friday)
|
||||||
|
self.assertIn(self.member_alice.id, team_a_saturday)
|
||||||
|
self.assertNotIn(self.member_alice.id, team_b_saturday)
|
||||||
|
|
||||||
|
def test_unassign_member_for_specific_date(self):
|
||||||
|
"""Vérifie que la désassignation supprime le membre uniquement pour la date cliquée."""
|
||||||
|
today = timezone.now().date()
|
||||||
|
target_d = today + timedelta(days=2)
|
||||||
|
|
||||||
|
# 1. Assigner Alice sur target_d
|
||||||
|
set_member_team_schedule(self.member_alice, self.team_a.id, target_d)
|
||||||
|
comp1 = get_teams_composition_for_period({self.team_a.id}, target_d, target_d)
|
||||||
|
self.assertIn(self.member_alice.id, [m['id'] for m in comp1.get((self.team_a.id, target_d), [])])
|
||||||
|
|
||||||
|
# 2. Désassigner Alice pour target_d (team_id=None)
|
||||||
|
url = reverse('contracts:team_planning_assign_member_ajax')
|
||||||
|
resp = self.client.post(url, data=json.dumps({
|
||||||
|
'member_id': self.member_alice.id,
|
||||||
|
'team_id': None,
|
||||||
|
'date': target_d.isoformat(),
|
||||||
|
}), content_type='application/json')
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
|
||||||
|
# 3. Vérifier que la cellule est désormais vide
|
||||||
|
comp2 = get_teams_composition_for_period({self.team_a.id}, target_d, target_d)
|
||||||
|
self.assertNotIn(self.member_alice.id, [m['id'] for m in comp2.get((self.team_a.id, target_d), [])])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue