Мелкие правки: обновлены serializers.py и views.py для procurement

This commit is contained in:
lizerk 2026-03-27 18:14:55 +03:00
parent decbadf47b
commit c61b62969a
2 changed files with 124 additions and 4 deletions

View File

@ -362,6 +362,7 @@ class EquipmentListSerializer(serializers.ModelSerializer):
read_only=True
)
is_under_warranty = serializers.BooleanField(read_only=True)
comments_count = serializers.IntegerField(read_only=True, default=0)
class Meta:
model = Equipment
@ -369,6 +370,7 @@ class EquipmentListSerializer(serializers.ModelSerializer):
'id',
'name',
'inventory_number',
'serial_number',
'category',
'category_name',
'category_icon',
@ -378,19 +380,27 @@ class EquipmentListSerializer(serializers.ModelSerializer):
'department_name',
'responsible_person',
'responsible_name',
'location',
'purchase_date',
'purchase_cost',
'notes',
'is_under_warranty',
'comments_count',
'created_at',
'updated_at',
]
read_only_fields = [
'id',
'inventory_number', # Генерируется автоматически
'inventory_number',
'category_name',
'category_icon',
'department_name',
'responsible_name',
'status_display',
'is_under_warranty',
'comments_count',
'created_at',
'updated_at',
]
def create(self, validated_data):

View File

@ -24,6 +24,8 @@ from procurement.models import (
ProcurementRequest,
Supplier,
)
from communications import comments_helpers
from communications.models import Message
from procurement.services import QRCodeGenerator
from .permissions import (
CanApproveProcurementRequest,
@ -875,15 +877,43 @@ class EquipmentViewSet(viewsets.ModelViewSet):
filters.SearchFilter,
filters.OrderingFilter,
]
filterset_fields = ['status', 'category', 'department']
filterset_fields = {
'status': ['exact'],
'category': ['exact'],
'department': ['exact'],
'responsible_person': ['exact'],
'purchase_date': ['gte', 'lte'],
}
search_fields = [
'name',
'inventory_number',
'serial_number',
'location',
]
ordering_fields = ['purchase_date', 'name']
ordering = ['-purchase_date']
ordering_fields = ['purchase_date', 'name', 'created_at']
ordering = ['-created_at']
def get_queryset(self):
"""Annotate comments_count."""
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, Subquery, OuterRef, IntegerField
from communications.models import Chat
ct = ContentType.objects.get_for_model(Equipment)
qs = super().get_queryset()
comments_sub = (
Chat.objects.filter(
type='comments',
context_content_type=ct,
context_object_id=OuterRef('pk'),
)
.annotate(msg_count=Count('messages', filter=Q(messages__is_deleted=False)))
.values('msg_count')[:1]
)
return qs.annotate(
comments_count=Subquery(comments_sub, output_field=IntegerField(default=0))
)
def get_serializer_class(self):
"""Выбрать сериализатор."""
@ -1240,6 +1270,86 @@ class EquipmentViewSet(viewsets.ModelViewSet):
return Response(data)
@action(detail=True, methods=['get', 'post'])
def comments(self, request, pk=None):
"""Список/создание комментариев для оборудования."""
from api.v1.employees.serializers.employee import (
EmployeeBriefSerializer,
)
equipment = self.get_object()
if request.method in ('GET', 'HEAD'):
messages = comments_helpers.get_comments(equipment)
comments_data = []
for msg in messages:
author_ser = EmployeeBriefSerializer(msg.author)
comments_data.append({
'id': msg.id,
'equipment': equipment.id,
'author': author_ser.data,
'text': msg.content,
'created_at': msg.created_at,
})
return Response(comments_data)
text = request.data.get('text', '').strip()
if not text:
return Response(
{'text': ['Это поле не может быть пустым.']},
status=status.HTTP_400_BAD_REQUEST,
)
message = comments_helpers.create_comment(
obj=equipment,
author=request.user,
content=text,
)
author_ser = EmployeeBriefSerializer(message.author)
return Response(
{
'id': message.id,
'equipment': equipment.id,
'author': author_ser.data,
'text': message.content,
'created_at': message.created_at,
},
status=status.HTTP_201_CREATED,
)
@action(
detail=True,
methods=['delete'],
url_path='comments/(?P<comment_id>[^/.]+)',
)
def delete_comment(self, request, pk=None, comment_id=None):
"""Удаление комментария к оборудованию."""
equipment = self.get_object()
chat = comments_helpers.get_or_create_comments_chat(equipment)
if isinstance(chat, tuple):
chat = chat[0]
try:
message = Message.objects.get(id=comment_id, chat=chat)
except Message.DoesNotExist:
return Response(
{'detail': 'Комментарий не найден'},
status=status.HTTP_404_NOT_FOUND,
)
if not (request.user.is_staff or message.author == request.user):
return Response(
{'detail': 'Нет прав на удаление'},
status=status.HTTP_403_FORBIDDEN,
)
comments_helpers.delete_comment(
message=message,
deleted_by=request.user,
soft_delete=True,
)
return Response(status=status.HTTP_204_NO_CONTENT)
class MaintenanceRecordViewSet(viewsets.ModelViewSet):
"""ViewSet для записей обслуживания."""