feat: enable backlog visibility for external managers in calendar view and expand status access permissions

This commit is contained in:
kdeterme 2026-08-17 16:05:21 +02:00
parent dcd35d843f
commit 122086e2ab
3 changed files with 66 additions and 5 deletions

View file

@ -383,6 +383,64 @@ class CalendarSearchTests(TestCase):
self.assertIn(self.intv_matching.id, feature_ids) self.assertIn(self.intv_matching.id, feature_ids)
self.assertNotIn(self.intv_other.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): class CalendarContractFilterTests(TestCase):
def setUp(self): def setUp(self):

View file

@ -371,7 +371,7 @@ def interventions_events(request):
end_window_filter = Q(effective_end__gte=start) | Q(effective_end__isnull=True) 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 = (
interventions interventions
.filter(end_window_filter) .filter(end_window_filter)

View file

@ -331,10 +331,11 @@ def _member_view_allowed_contract_ids(
user_config: Optional[UserConfig], user_config: Optional[UserConfig],
role_names: Set[str], role_names: Set[str],
) -> Optional[Set[int]]: ) -> 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 Used to restrict the backlog (right panel) to interventions the user could
actually assign for processing. actually assign or plan.
""" """
if not user_config: if not user_config:
return set() return set()
@ -344,8 +345,10 @@ def _member_view_allowed_contract_ids(
contract_ids = UserContractAccess.objects.filter( contract_ids = UserContractAccess.objects.filter(
user_config=user_config, user_config=user_config,
can_view_interventions=True, can_view_interventions=True,
status_permissions__status='to_be_processed', ).filter(
status_permissions__can_change_status_to=True, 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) ).values_list('contract_id', flat=True)
return {cid for cid in contract_ids if cid is not None} return {cid for cid in contract_ids if cid is not None}