feat(home): filter controller shortcuts link by assigned controller and remove sub-counters
- Remove 'to_be_corrected' and 'validated' sub-counters from controller shortcuts widget - Include assigned_controller parameter in widget URL using the new role-person filter - Update ControllerShortcutsWidgetTests to assert URL parameter and absence of sub-counters
This commit is contained in:
parent
3d9e7c3202
commit
6782959253
3 changed files with 28 additions and 33 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
{# ========== Widget raccourcis pour les contrôleurs ========== #}
|
{# ========== Widget raccourcis pour les contrôleurs ========== #}
|
||||||
<div class="card shadow-sm h-100" style="border-color: #00897b !important;">
|
<div class="card shadow-sm h-100" style="border-color: #00897b !important;">
|
||||||
<div class="card-header d-flex align-items-center justify-content-between text-white" style="background-color: #00897b !important;">
|
<div class="card-header d-flex align-items-center justify-content-between text-white" style="background-color: #00897b !important;">
|
||||||
<a href="{% url 'interventions:interventions_index' %}?status=finished&status=processed&status=corrected"
|
<a href="{{ controller_shortcuts_url }}"
|
||||||
class="text-decoration-none fw-bold text-uppercase text-white d-flex align-items-center" style="letter-spacing:.05em;">
|
class="text-decoration-none fw-bold text-uppercase text-white d-flex align-items-center" style="letter-spacing:.05em;">
|
||||||
<i class="bi bi-patch-check-fill me-2 fs-5"></i>
|
<i class="bi bi-patch-check-fill me-2 fs-5"></i>
|
||||||
<span>{% translate "Interventions à contrôler" %}</span>
|
<span>{% translate "Interventions à contrôler" %}</span>
|
||||||
|
|
@ -13,23 +13,13 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# --- Compteur principal et sous-raccourcis --- #}
|
{# --- Compteur principal --- #}
|
||||||
<div class="text-center py-2 border-bottom bg-light bg-opacity-25">
|
<div class="text-center py-2 border-bottom bg-light bg-opacity-25">
|
||||||
<a href="{% url 'interventions:interventions_index' %}?status=finished&status=processed&status=corrected"
|
<a href="{{ controller_shortcuts_url }}"
|
||||||
class="text-decoration-none d-block">
|
class="text-decoration-none d-block">
|
||||||
<span class="display-5 fw-bold" style="color: #00897b !important;">{{ controller_interventions_count }}</span>
|
<span class="display-5 fw-bold" style="color: #00897b !important;">{{ controller_interventions_count }}</span>
|
||||||
<div class="small text-muted fw-semibold">{% translate "en attente de contrôle" %}</div>
|
<div class="small text-muted fw-semibold">{% translate "en attente de contrôle" %}</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="d-flex justify-content-center gap-2 mt-2">
|
|
||||||
<a href="{% url 'interventions:interventions_index' %}?status=to_be_corrected"
|
|
||||||
class="badge text-decoration-none bg-warning-subtle text-warning-emphasis border border-warning-subtle">
|
|
||||||
<i class="bi bi-arrow-repeat me-1"></i>{% translate "À corriger" %} ({{ controller_to_correct_count|default:0 }})
|
|
||||||
</a>
|
|
||||||
<a href="{% url 'interventions:interventions_index' %}?status=validated"
|
|
||||||
class="badge text-decoration-none bg-success-subtle text-success-emphasis border border-success-subtle">
|
|
||||||
<i class="bi bi-check-all me-1"></i>{% translate "Validées" %} ({{ controller_validated_count|default:0 }})
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# --- Liste des 5 premières interventions --- #}
|
{# --- Liste des 5 premières interventions --- #}
|
||||||
|
|
@ -64,7 +54,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="card-footer text-center text-muted small bg-light">
|
<div class="card-footer text-center text-muted small bg-light">
|
||||||
<a href="{% url 'interventions:interventions_index' %}?status=finished&status=processed&status=corrected"
|
<a href="{{ controller_shortcuts_url }}"
|
||||||
class="text-decoration-none" style="color: #00897b !important; font-weight: 500;">
|
class="text-decoration-none" style="color: #00897b !important; font-weight: 500;">
|
||||||
<i class="bi bi-arrow-right-circle me-1"></i>{% translate "Voir toutes les interventions à contrôler" %}
|
<i class="bi bi-arrow-right-circle me-1"></i>{% translate "Voir toutes les interventions à contrôler" %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,11 @@ class ControllerShortcutsWidgetTests(TestCase):
|
||||||
self.assertContains(response, 'ITV-CTRL-000')
|
self.assertContains(response, 'ITV-CTRL-000')
|
||||||
self.assertContains(response, 'ITV-CTRL-001')
|
self.assertContains(response, 'ITV-CTRL-001')
|
||||||
self.assertContains(response, 'ITV-CTRL-002')
|
self.assertContains(response, 'ITV-CTRL-002')
|
||||||
self.assertContains(response, 'status=finished&status=processed&status=corrected')
|
self.assertContains(response, f'assigned_controller={self.member.id}')
|
||||||
|
self.assertNotContains(response, 'À corriger')
|
||||||
|
self.assertNotContains(response, 'Validées')
|
||||||
|
self.assertNotIn('controller_to_correct_count', response.context)
|
||||||
|
self.assertNotIn('controller_validated_count', response.context)
|
||||||
|
|
||||||
|
|
||||||
class StockSummaryWidgetTests(TestCase):
|
class StockSummaryWidgetTests(TestCase):
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ def _t(label, t0, splits):
|
||||||
|
|
||||||
from interventions.models import Intervention, InterventionTimeLine, STATUS_ORDERS, Symptom
|
from interventions.models import Intervention, InterventionTimeLine, STATUS_ORDERS, Symptom
|
||||||
from common.models import UserConfig, UserThematics, UserContractAccess
|
from common.models import UserConfig, UserThematics, UserContractAccess
|
||||||
from contracts.models import CompanyMember, Contract
|
from contracts.models import CompanyMember, CompanyTeam, Contract
|
||||||
from contracts.permissions import get_allowed_contracts_for_user
|
from contracts.permissions import get_allowed_contracts_for_user
|
||||||
from home.models import HomeWidget
|
from home.models import HomeWidget
|
||||||
from observations.models import Observation
|
from observations.models import Observation
|
||||||
|
|
@ -674,14 +674,22 @@ def index(request):
|
||||||
# ========== Données widget controller_shortcuts ==========
|
# ========== Données widget controller_shortcuts ==========
|
||||||
user_role_names = set(user_config.roles.values_list('name', flat=True)) if user_config else set()
|
user_role_names = set(user_config.roles.values_list('name', flat=True)) if user_config else set()
|
||||||
controller_filter = Q(status__in=['finished', 'processed', 'corrected'])
|
controller_filter = Q(status__in=['finished', 'processed', 'corrected'])
|
||||||
|
|
||||||
|
controller_member = (
|
||||||
|
CompanyMember.objects.filter(
|
||||||
|
user=request.user,
|
||||||
|
teams__operation_types__contains=[CompanyTeam.OPERATION_CONTROLS]
|
||||||
|
).first()
|
||||||
|
or CompanyMember.objects.filter(user=request.user).first()
|
||||||
|
)
|
||||||
|
controller_member_id = controller_member.id if controller_member else None
|
||||||
|
|
||||||
if not (user_role_names & {'admin', 'top_manager', 'manager'}):
|
if not (user_role_names & {'admin', 'top_manager', 'manager'}):
|
||||||
control_team_ids = list(user_teams.values_list('id', flat=True)) if (user_teams and user_teams.exists()) else []
|
if controller_member:
|
||||||
controller_q = Q(assigned_controller__user=request.user)
|
controller_q = Q(assigned_controller=controller_member)
|
||||||
if control_team_ids:
|
|
||||||
controller_q |= Q(assigned_control_team_id__in=control_team_ids)
|
|
||||||
controller_filter &= controller_q
|
|
||||||
else:
|
else:
|
||||||
controller_q = None
|
controller_q = Q(assigned_controller__user=request.user)
|
||||||
|
controller_filter &= controller_q
|
||||||
|
|
||||||
controller_interventions_qs = interventions.filter(controller_filter)
|
controller_interventions_qs = interventions.filter(controller_filter)
|
||||||
controller_interventions_count = controller_interventions_qs.count()
|
controller_interventions_count = controller_interventions_qs.count()
|
||||||
|
|
@ -691,15 +699,9 @@ def index(request):
|
||||||
.order_by('-code')[:5]
|
.order_by('-code')[:5]
|
||||||
)
|
)
|
||||||
|
|
||||||
controller_to_correct_qs = interventions.filter(status='to_be_corrected')
|
controller_shortcuts_url = reverse('interventions:interventions_index') + '?status=finished&status=processed&status=corrected'
|
||||||
if controller_q is not None:
|
if controller_member_id:
|
||||||
controller_to_correct_qs = controller_to_correct_qs.filter(controller_q)
|
controller_shortcuts_url += f'&assigned_controller={controller_member_id}'
|
||||||
controller_to_correct_count = controller_to_correct_qs.count()
|
|
||||||
|
|
||||||
controller_validated_qs = interventions.filter(status='validated')
|
|
||||||
if controller_q is not None:
|
|
||||||
controller_validated_qs = controller_validated_qs.filter(controller_q)
|
|
||||||
controller_validated_count = controller_validated_qs.count()
|
|
||||||
|
|
||||||
# ========== Données widget external_interventions ==========
|
# ========== Données widget external_interventions ==========
|
||||||
user_company_ids = set()
|
user_company_ids = set()
|
||||||
|
|
@ -859,8 +861,7 @@ def index(request):
|
||||||
'external_interventions_list': external_interventions_list,
|
'external_interventions_list': external_interventions_list,
|
||||||
'controller_interventions_count': controller_interventions_count,
|
'controller_interventions_count': controller_interventions_count,
|
||||||
'controller_interventions_list': controller_interventions_list,
|
'controller_interventions_list': controller_interventions_list,
|
||||||
'controller_to_correct_count': controller_to_correct_count,
|
'controller_shortcuts_url': controller_shortcuts_url,
|
||||||
'controller_validated_count': controller_validated_count,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Logging de performance (désactivé) ────────────────────────────────
|
# ── Logging de performance (désactivé) ────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue