Corp/backend/api/v1/commerce/viewsets.py
2026-08-17 18:38:22 +03:00

133 lines
4.6 KiB
Python

from django.db.models import Count
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from commerce.models import (
Cost,
Product,
ProductBinding,
Sale,
SaleLine,
SourceSystem,
StockSnapshot,
)
from commerce.services import get_product_metrics
from .permissions import CommerceAccessPermission
from .serializers import (
CostSerializer,
ProductBindingSerializer,
ProductMetricsQuerySerializer,
ProductSerializer,
SaleSerializer,
SaleLineSerializer,
SourceSystemSerializer,
StockSnapshotSerializer,
)
class SourceSystemViewSet(viewsets.ModelViewSet):
queryset = SourceSystem.objects.all()
serializer_class = SourceSystemSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ["code", "name"]
ordering_fields = ["code", "name", "created_at"]
ordering = ["name"]
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [
DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
]
filterset_fields = ["kind", "is_active", "parent"]
search_fields = ["sku", "name", "barcode", "bindings__external_sku"]
ordering_fields = ["sku", "name", "created_at", "updated_at"]
ordering = ["name", "sku"]
def get_queryset(self):
return (
super()
.get_queryset()
.select_related("parent")
.prefetch_related("bindings__source")
.annotate(variants_count=Count("variants", distinct=True))
.distinct()
)
@action(detail=True, methods=["get"])
def analytics(self, request, pk=None):
query = ProductMetricsQuerySerializer(data=request.query_params)
query.is_valid(raise_exception=True)
product = self.get_object()
return Response(get_product_metrics(product, **query.validated_data))
class ProductBindingViewSet(viewsets.ModelViewSet):
queryset = ProductBinding.objects.select_related("product", "source")
serializer_class = ProductBindingSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = ["product", "source", "is_primary"]
search_fields = ["external_id", "external_sku", "product__sku", "product__name"]
class SaleViewSet(viewsets.ModelViewSet):
queryset = Sale.objects.select_related("source", "source_record").prefetch_related(
"lines__product"
)
serializer_class = SaleSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [
DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
]
filterset_fields = [
"source",
"event_type",
"channel",
"status",
"counts_as_sale",
"currency",
]
search_fields = ["external_id", "number", "lines__external_sku", "lines__name"]
ordering_fields = ["occurred_at", "created_at", "updated_at"]
ordering = ["-occurred_at"]
class SaleLineViewSet(viewsets.ModelViewSet):
queryset = SaleLine.objects.select_related("sale", "product", "sale__source")
serializer_class = SaleLineSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_fields = ["sale", "product"]
search_fields = ["external_id", "external_product_id", "external_sku", "name"]
class CostViewSet(viewsets.ModelViewSet):
queryset = Cost.objects.select_related("source", "product", "sale_line")
serializer_class = CostSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ["source", "product", "channel", "cost_type", "currency"]
ordering_fields = ["occurred_at", "amount", "created_at"]
ordering = ["-occurred_at"]
class StockSnapshotViewSet(viewsets.ModelViewSet):
queryset = StockSnapshot.objects.select_related("source", "product")
serializer_class = StockSnapshotSerializer
permission_classes = [CommerceAccessPermission]
filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ["source", "product", "warehouse_external_id"]
ordering_fields = ["captured_at", "quantity", "created_at"]
ordering = ["-captured_at"]