Игорь Надеин d6e7e4ae08 refactor(procurement): replace Celery with NotificationService
BREAKING CHANGE: Removed Celery tasks in favor of existing notification system

Changes:
- ❌ Deleted tasks.py (261 lines) - Celery tasks removed
- ✅ Updated views.py - replaced .delay() calls with NotificationService
- ✅ Updated README.md - documented NotificationService integration
- ✅ Updated PROCUREMENT_IMPLEMENTATION_PLAN.md - architectural decision

Architecture Decision:
- Use NotificationService instead of Celery for notifications
- Supports Web (WebSocket), Email (HTML), Telegram channels
- Simpler deployment (no worker processes needed)
- Sufficient for 50-200 employees, <10 requests/day
- 0.5-2s email delay is acceptable for rare operations

Benefits:
- -2 production processes (no celery worker/beat)
- Easier debugging (sync execution, same logs)
- Already tested and used across all modules
- No DevOps overhead

Net result: -164 lines of code, simpler architecture
2025-12-09 09:19:58 +03:00

295 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Модуль "Закупки и инвентарь" (Procurement)
## Описание
Модуль для управления внутренними закупками по отделам и учета оборудования/инвентаря.
## Основные возможности
### 1. Заявки на закупку
- Создание заявок с позициями (товары/услуги)
- Автоматический маршрут согласования по сумме:
- До 10,000₽ — только руководитель отдела
- 10,000-50,000₽ — руководитель отдела + финансовый менеджер
- Свыше 50,000₽ — руководитель отдела + фин. менеджер + директор
- Отслеживание статуса: черновик → согласование → одобрено → в работе → завершено
- Уровни срочности: низкая, средняя, высокая, критическая
### 2. Бюджетный контроль
- Бюджеты по отделам и кварталам
- Автоматическая проверка доступности средств при создании заявки
- Отслеживание использования бюджета в процентах
### 3. Инвентаризация оборудования
- Учет оборудования с инвентарными номерами
- Иерархические категории оборудования
- Статусы: доступно, в использовании, на обслуживании, в ремонте, списано, утеряно
- Привязка к отделам и ответственным лицам
- Отслеживание гарантийных сроков
### 4. Техническое обслуживание
- История обслуживания оборудования
- Типы ТО: осмотр, плановое ТО, ремонт, модернизация, чистка
- Планирование следующего обслуживания
### 5. Поставщики
- База данных поставщиков
- Контактная информация
- Рейтинги поставщиков
## Модели данных
1. **ProcurementRequest** — заявки на закупку
2. **ProcurementItem** — позиции в заявках
3. **Approval** — записи согласований
4. **Budget** — бюджеты отделов по кварталам
5. **Equipment** — оборудование/инвентарь
6. **EquipmentCategory** — категории оборудования (иерархические)
7. **MaintenanceRecord** — записи техобслуживания
8. **Supplier** — поставщики
## Stage 1: Базовая структура ✅
### Выполнено:
- ✅ Создано Django-приложение `procurement`
- ✅ Определены все константы и enums в `constants.py`
- ✅ Созданы 8 моделей данных в `models.py`
- ✅ Созданы и применены миграции
- ✅ Настроена админ-панель с инлайнами и цветными бадами
- ✅ Приложение добавлено в `INSTALLED_APPS`
- ✅ Написано 20 unit-тестов (все прошли)
## Stage 2: API и права доступа ✅
### Выполнено:
- ✅ Созданы permissions для всех ролей
- `IsDepartmentHead` - руководитель отдела
- `IsFinanceManager` - финансовый менеджер
- `IsDirector` - директор
- `CanCreateProcurementRequest` - создание заявок
- `CanEditOwnProcurementRequest` - редактирование своих заявок
- `CanApproveProcurementRequest` - согласование заявок
- `CanManageEquipment` - управление оборудованием
- `CanManageBudget` - управление бюджетами
- `CanManageSupplier` - управление поставщиками
- ✅ Созданы сериализаторы для всех моделей
- List/Detail варианты для разной степени детализации
- Вложенные сериализаторы для связанных объектов
- Computed fields (total_price, is_editable, budget_available)
- ✅ Созданы ViewSets с полным функционалом
- CRUD операции для всех моделей
- Фильтрация, поиск, сортировка
- Custom actions:
- `submit` - отправить заявку на согласование
- `approve` - одобрить заявку
- `reject` - отклонить заявку
- `my_requests` - мои заявки
- `pending_approvals` - заявки на согласовании
- `my_equipment` - мое оборудование
- `warranty_expiring` - истекающие гарантии
- `current_quarter` - бюджеты текущего квартала
- `top_rated` - лучшие поставщики
- ✅ Подключен django-filter для фильтрации
- ✅ URL routing настроен
### API Endpoints:
**Заявки на закупку:**
- `GET /api/procurement/requests/` - список заявок
- `POST /api/procurement/requests/` - создать заявку
- `GET /api/procurement/requests/{id}/` - детали заявки
- `PUT/PATCH /api/procurement/requests/{id}/` - обновить заявку
- `DELETE /api/procurement/requests/{id}/` - удалить заявку
- `POST /api/procurement/requests/{id}/submit/` - отправить на согласование
- `POST /api/procurement/requests/{id}/approve/` - одобрить
- `POST /api/procurement/requests/{id}/reject/` - отклонить
- `GET /api/procurement/requests/my_requests/` - мои заявки
- `GET /api/procurement/requests/pending_approvals/` - на согласовании
**Позиции заявок:**
- `GET /api/procurement/items/` - список позиций
- `POST /api/procurement/items/` - создать позицию
- `GET /api/procurement/items/{id}/` - детали позиции
- `PUT/PATCH /api/procurement/items/{id}/` - обновить
- `DELETE /api/procurement/items/{id}/` - удалить
**Оборудование:**
- `GET /api/procurement/equipment/` - список оборудования
- `POST /api/procurement/equipment/` - добавить оборудование
- `GET /api/procurement/equipment/{id}/` - детали
- `PUT/PATCH /api/procurement/equipment/{id}/` - обновить
- `DELETE /api/procurement/equipment/{id}/` - удалить
- `GET /api/procurement/equipment/my_equipment/` - мое оборудование
- `GET /api/procurement/equipment/warranty_expiring/` - истекающие гарантии
**Категории оборудования:**
- `GET /api/procurement/equipment-categories/` - список категорий
- `POST /api/procurement/equipment-categories/` - создать категорию
- `GET /api/procurement/equipment-categories/tree/` - дерево категорий
- `GET /api/procurement/equipment-categories/{id}/children/` - подкатегории
**Техническое обслуживание:**
- `GET /api/procurement/maintenance/` - записи обслуживания
- `POST /api/procurement/maintenance/` - создать запись
- `GET /api/procurement/maintenance/{id}/` - детали
- `PUT/PATCH /api/procurement/maintenance/{id}/` - обновить
- `DELETE /api/procurement/maintenance/{id}/` - удалить
**Бюджеты:**
- `GET /api/procurement/budgets/` - список бюджетов
- `POST /api/procurement/budgets/` - создать бюджет
- `GET /api/procurement/budgets/{id}/` - детали
- `PUT/PATCH /api/procurement/budgets/{id}/` - обновить
- `DELETE /api/procurement/budgets/{id}/` - удалить
- `GET /api/procurement/budgets/current_quarter/` - текущий квартал
**Поставщики:**
- `GET /api/procurement/suppliers/` - список поставщиков
- `POST /api/procurement/suppliers/` - создать поставщика
- `GET /api/procurement/suppliers/{id}/` - детали
- `PUT/PATCH /api/procurement/suppliers/{id}/` - обновить
- `DELETE /api/procurement/suppliers/{id}/` - удалить
- `GET /api/procurement/suppliers/top_rated/` - лучшие поставщики
### Фильтрация и поиск:
**Заявки:**
- Фильтры: `?status=pending&urgency=high&department=1`
- Поиск: `?search=ноутбук`
- Сортировка: `?ordering=-created_at`
**Оборудование:**
- Фильтры: `?status=available&category=1&department=2`
- Поиск: `?search=INV-2025`
**Бюджеты:**
- Фильтры: `?year=2025&quarter=4&department=1`
**Поставщики:**
- Фильтры: `?is_active=true`
- Поиск: `?search=ООО`
### Администрирование
Все модели доступны через Django Admin:
- `/admin/procurement/procurementrequest/` — заявки
- `/admin/procurement/equipment/` — оборудование
- `/admin/procurement/budget/` — бюджеты
- `/admin/procurement/supplier/` — поставщики
- и т.д.
## Stage 3: Workflow и уведомления ✅
### Выполнено:
- ✅ Установлен django-fsm 3.0.1
- ✅ Созданы сигналы для автоматических уведомлений (signals.py)
- `notify_on_request_status_change` - уведомления при изменении статуса заявки
- `notify_on_approval_change` - уведомления при согласовании/отклонении
- `notify_approvers` - уведомление всех согласующих
- `notify_requestor` - уведомление создателя заявки
- Интеграция с NotificationService из существующей системы
- ✅ Интегрирована система уведомлений (NotificationService)
- Web уведомления через WebSocket (real-time)
- Email уведомления с HTML шаблонами
- Telegram уведомления через Bot API
- Настройки пользователя для каналов доставки
- ✅ Интегрированы уведомления в ViewSet actions
- При submit: отправка уведомлений всем согласующим
- При approve: уведомление создателя + статус этапа
- При reject: уведомление создателя с причиной
- ✅ Подключены сигналы в apps.py (ready())
- ✅ Написано 9 workflow тестов (test_workflow.py)
- 1/9 проходят (остальные падают из-за items_count bug из Stage 2)
### Workflow согласований:
```
DRAFT (Черновик)
↓ submit()
PENDING (На согласовании)
↓ approve() [все одобрили] ↓ reject() [хотя бы один отклонил]
APPROVED (Одобрено) REJECTED (Отклонено)
↓ start_work()
IN_PROGRESS (В работе)
↓ complete()
COMPLETED (Завершено)
```
### Типы уведомлений:
**Все уведомления отправляются через NotificationService:**
- ✅ **Web** - мгновенные уведомления в браузере через WebSocket
- ✅ **Email** - HTML письма с красивым оформлением
- ✅ **Telegram** - уведомления в мессенджере (если настроено)
**События:**
1. **При создании заявки**: Web уведомление руководителю отдела
2. **При отправке на согласование**: Web + Email всем согласующим
3. **При одобрении этапа**: Web + Email создателю о прохождении этапа
4. **При полном одобрении**: Web + Email создателю о возможности приступить к закупке
5. **При отклонении**: Web + Email создателю с комментариями отклонившего
6. **При превышении бюджета**: Уведомления через signals (реализовано в сигналах)
### Известные проблемы (унаследованы из Stage 2):
- ❌ items_count property конфликтует с annotate() - требует SerializerMethodField
- ❌ Из-за этого 8/9 workflow тестов не могут выполнить get_object()
### Архитектурные решения:
- ✅ **Использована NotificationService вместо Celery**
- Причина: встроенная система уже поддерживает Web/Email/Telegram
- Преимущества: простота, нет дополнительных процессов, легче debugging
- Масштаб: достаточно для 50-200 сотрудников и <10 заявок/день
- Задержка 0.5-2 секунды на отправку email приемлема для редких операций
### Следующие шаги:
- Исправить баг items_count из Stage 2
- Добавить типы уведомлений в базу NotificationType (если не созданы)
- Добавить FSM transitions в модель (опционально, текущая реализация функциональна)
## Следующие этапы
### Stage 4: Бюджетный контроль
- Аналитика и отчеты по бюджетам
- Dashboard с графиками
- Прогнозирование расходов
### Stage 5: Инвентаризация
- QR-коды для оборудования
- Мобильное сканирование
- Планирование ТО
### Stage 6: Frontend
- Интерфейсы создания заявок
- Dashboard согласований
- Каталог оборудования
### Stage 7: Интеграции
- Связь с финансовым модулем
- Интеграция с календарем (ТО)
- Экспорт отчетов в Excel/PDF
### Stage 8: Тестирование
- Unit tests для моделей
- API tests
- Integration tests
## Технологический стек
- **Backend**: Django 5.2.4
- **State Machine**: django-fsm 3.0.1 ✅
- **Notifications**: NotificationService (встроенная система) ✅
- Web уведомления: Django Channels + WebSocket
- Email: HTML шаблоны через common.emails
- Telegram: Bot API
- **Scheduler**: APScheduler 3.11+ (для periodic tasks)
- **Charts**: Chart.js (планируется)
- **Barcodes**: python-barcode, qrcode (планируется)
- **Reports**: reportlab (планируется)
## Разработка
Подробный план на 1-2 месяца см. в `PROCUREMENT_IMPLEMENTATION_PLAN.md`