diff --git a/loko/interventions/tests/test_calendar.py b/loko/interventions/tests/test_calendar.py index 7d8402d..553e8dd 100644 --- a/loko/interventions/tests/test_calendar.py +++ b/loko/interventions/tests/test_calendar.py @@ -383,6 +383,64 @@ class CalendarSearchTests(TestCase): self.assertIn(self.intv_matching.id, feature_ids) self.assertNotIn(self.intv_other.id, feature_ids) + def test_calendar_events_external_manager_backlog_visibility(self): + User = get_user_model() + ext_user = User.objects.create_user(username='ext-mgr', password='pwd') + role_ext, _ = Role.objects.get_or_create(name='external_manager') + ext_config = UserConfig.objects.create(user=ext_user, is_intern=False) + ext_config.roles.add(role_ext) + + from common.models import UserContractAccess, UserContractStatusPermission + from contracts.models import UserCompanyTeamAccess + company = Company.objects.create(name='Company Ext') + contract = Contract.objects.create( + company=company, + contract_number="C-TEST-01", + start_date=timezone.now().date() - timedelta(days=30), + end_date=timezone.now().date() + timedelta(days=365) + ) + contract_access = UserContractAccess.objects.create( + user_config=ext_config, + contract=contract, + can_view_interventions=True + ) + UserContractStatusPermission.objects.create( + user_contract=contract_access, + status='to_be_processed', + can_view=True, + can_change_status_to=False, + ) + UserThematics.objects.create( + user_config=ext_config, + thematic=self.thematic, + can_view_interventions=True + ) + team = CompanyTeam.objects.create(name='Team Ext', company=company) + team.thematics.add(self.thematic) + UserCompanyTeamAccess.objects.create( + user_config=ext_config, + team=team, + can_view=True + ) + + itv_backlog = Intervention.objects.create( + title='Intervention for External Manager', + status='to_be_processed', + maintain_type='corrective', + contract=contract, + thematic=self.thematic, + ) + + self.client.login(username='ext-mgr', password='pwd') + url = reverse('interventions:interventions_events') + '?view_mode=teams_daily' + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + data = response.json() + self.assertIn('backlog_groups', data) + corrective_backlog = data['backlog_groups'].get('corrective', []) + corrective_ids = [i['id'] for i in corrective_backlog] + self.assertIn(itv_backlog.id, corrective_ids) + class CalendarContractFilterTests(TestCase): def setUp(self): diff --git a/loko/interventions/views/calendar.py b/loko/interventions/views/calendar.py index a843d02..9780f2e 100644 --- a/loko/interventions/views/calendar.py +++ b/loko/interventions/views/calendar.py @@ -371,7 +371,7 @@ def interventions_events(request): end_window_filter = Q(effective_end__gte=start) | Q(effective_end__isnull=True) - if view_mode == 'members': + if view_mode in ('members', 'teams_daily'): interventions = ( interventions .filter(end_window_filter) diff --git a/loko/interventions/views/helpers.py b/loko/interventions/views/helpers.py index 755e835..08127c8 100644 --- a/loko/interventions/views/helpers.py +++ b/loko/interventions/views/helpers.py @@ -331,10 +331,11 @@ def _member_view_allowed_contract_ids( user_config: Optional[UserConfig], role_names: Set[str], ) -> Optional[Set[int]]: - """Return contract IDs for which the user can change status to 'to_be_processed'. + """Return contract IDs for which the user can change status to 'to_be_processed' or 'assigned', + or contracts accessible to external managers. Used to restrict the backlog (right panel) to interventions the user could - actually assign for processing. + actually assign or plan. """ if not user_config: return set() @@ -344,8 +345,10 @@ def _member_view_allowed_contract_ids( contract_ids = UserContractAccess.objects.filter( user_config=user_config, can_view_interventions=True, - status_permissions__status='to_be_processed', - status_permissions__can_change_status_to=True, + ).filter( + Q(status_permissions__status__in=['to_be_processed', 'assigned', 'to_be_planned', 'in_progress'], + status_permissions__can_change_status_to=True) + | Q(user_config__roles__name='external_manager') ).values_list('contract_id', flat=True) return {cid for cid in contract_ids if cid is not None}