From 47bf0cbcb94425ba7e9fafadb880d5d6f0d599f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=9D=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Tue, 3 Nov 2026 10:06:17 +0300 Subject: [PATCH] Notify processing departments about subscriptions --- backend/procurement/application/requests.py | 2 - backend/procurement/notifications/config.py | 16 ++++-- backend/procurement/notifications/handlers.py | 1 + backend/procurement/notifications/signals.py | 5 -- .../procurement/test_procurement_requests.py | 57 +++++++++++++++++++ frontend/src/app/procurement/page.tsx | 11 +++- 6 files changed, 80 insertions(+), 12 deletions(-) diff --git a/backend/procurement/application/requests.py b/backend/procurement/application/requests.py index 8a4e7d64..cfdcf873 100644 --- a/backend/procurement/application/requests.py +++ b/backend/procurement/application/requests.py @@ -51,8 +51,6 @@ def create_procurement_request( **request_attributes, ) procurement_request._notification_actor = requestor - if procurement_request.request_type == ProcurementRequest.RequestType.SUBSCRIPTION: - procurement_request._suppress_created_procurement_notifications = True procurement_request.save() for raw_item in items: diff --git a/backend/procurement/notifications/config.py b/backend/procurement/notifications/config.py index 7e5dc584..8fefb738 100644 --- a/backend/procurement/notifications/config.py +++ b/backend/procurement/notifications/config.py @@ -62,11 +62,19 @@ class MessageTemplates: title: str, department_name: str, author_name: str, + request_type: str = "standard", ) -> tuple[str, str]: - notification_title = "Новая заявка на закупку" - description = ( - f'{author_name} направил заявку "{title}" в отдел {department_name}.' - ) + if request_type == "subscription": + notification_title = "Новая заявка на подписку" + description = ( + f'{author_name} направил заявку на подписку "{title}" ' + f"в отдел {department_name}." + ) + else: + notification_title = "Новая заявка на закупку" + description = ( + f'{author_name} направил заявку "{title}" в отдел {department_name}.' + ) return notification_title, description @staticmethod diff --git a/backend/procurement/notifications/handlers.py b/backend/procurement/notifications/handlers.py index 8a2514e5..3efcd193 100644 --- a/backend/procurement/notifications/handlers.py +++ b/backend/procurement/notifications/handlers.py @@ -198,6 +198,7 @@ def notify_processing_department_request(request, actor=None): request.title, department_name, _actor_name(actor), + request_type=request.request_type, ) recipients = _processing_department_recipients(request) _notify_many( diff --git a/backend/procurement/notifications/signals.py b/backend/procurement/notifications/signals.py index 4e96974f..e099c9bc 100644 --- a/backend/procurement/notifications/signals.py +++ b/backend/procurement/notifications/signals.py @@ -49,11 +49,6 @@ def create_request_notifications(sender, instance, created, **kwargs): if ( request.status == ProcurementStatus.WAITING and request.processing_department_id - and not getattr( - request, - "_suppress_created_procurement_notifications", - False, - ) ): notify_processing_department_request( request, diff --git a/backend/tests/api/v1/procurement/test_procurement_requests.py b/backend/tests/api/v1/procurement/test_procurement_requests.py index 3faa8eaf..f4de3ab3 100644 --- a/backend/tests/api/v1/procurement/test_procurement_requests.py +++ b/backend/tests/api/v1/procurement/test_procurement_requests.py @@ -1487,6 +1487,63 @@ class TestProcessingDepartmentWorkflow: ) return employee + def test_subscription_creation_notifies_approver_and_processing_department( + self, + user, + department, + supply_department, + supply_user, + ): + from procurement.application import create_procurement_request + + approver = Employee.objects.create_user( + email="subscription-approver@example.com", + password="testpass123", + phone_number="+79998888894", + first_name="Согласующий", + last_name="Подписок", + is_active=True, + email_verified=True, + send_activation_email=False, + ) + procurement_settings = ProcurementSettings.get_solo() + procurement_settings.subscription_approver = approver + procurement_settings.save(update_fields=["subscription_approver"]) + + procurement_request = create_procurement_request( + requestor=user, + attributes={ + "title": "Подписка на сервис", + "request_type": ProcurementRequest.RequestType.SUBSCRIPTION, + "description": "Ежемесячный доступ к сервису", + "department": department, + "processing_department": supply_department, + "urgency": UrgencyLevel.MEDIUM, + }, + items=[], + ) + + assert procurement_request.status == ProcurementStatus.PENDING + request_id = procurement_request.id + assert Approval.objects.filter( + request_id=request_id, + approver=approver, + status=ApprovalStatus.PENDING, + ).exists() + assert Notification.objects.filter( + recipient=approver, + verb="procurement_pending_approval", + data__request_id=request_id, + ).exists() + + department_notification = Notification.objects.get( + recipient=supply_user, + verb="procurement_department_request", + data__request_id=request_id, + ) + assert department_notification.data["title"] == "Новая заявка на подписку" + assert "направил заявку на подписку" in department_notification.description + @pytest.fixture def supply_role_user(self, db, supply_department): employee = Employee.objects.create_user( diff --git a/frontend/src/app/procurement/page.tsx b/frontend/src/app/procurement/page.tsx index b0021ece..cc7d43a4 100644 --- a/frontend/src/app/procurement/page.tsx +++ b/frontend/src/app/procurement/page.tsx @@ -1215,9 +1215,18 @@ export default function ProcurementPage() { type="button" onClick={() => setScope("subscriptions")} aria-pressed={scope === "subscriptions"} - className={`inline-flex h-8 items-center rounded-full px-3 text-xs font-medium transition ${scope === "subscriptions" ? "app-pill-active" : "app-pill"}`} + className={`inline-flex h-8 items-center gap-1.5 rounded-full px-3 text-xs font-medium transition ${scope === "subscriptions" ? "app-pill-active" : "app-pill"}`} > Подписки + + {scopeCounts.subscriptions ?? 0} +