133 lines
4.6 KiB
Python
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"]
|