Files
shoppy/shop/api/v1/viewsets.py
T
2024-11-22 08:30:26 +01:00

186 lines
5.9 KiB
Python

from decimal import Decimal
from django.db import transaction
from django.db.models.deletion import ProtectedError
from django.shortcuts import get_object_or_404
from django.utils.text import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAdminUser
from rest_framework.viewsets import ModelViewSet
from shop.api.v1.permissions import ProductPermissions, ProductPricePermissions
from shop.api.v1.serializers import (BrandSerializer,
CreateProductPriceSerializer,
CreateProductSerializer,
CustomerSerializer, ListProductSerializer,
OrderLineSerializer, OrderSerializer,
ProductBatchSerializer,
ProductPriceSerializer, ProductSerializer,
ProviderSerializer, TagSerializer,
TaxSerializer, UpdateProductSerializer)
from shop.filters import ProductFilter
from shop.models import (Brand, Customer, Order, OrderLine, Product,
ProductBatch, ProductPrice, Provider, Tag, Tax)
from shop.utils import delete_product_batch
class ProductViewSet(ModelViewSet):
serializer_class = ProductSerializer
queryset = (
Product.objects.prefetch_related("prices")
.prefetch_related("tags")
.prefetch_related("images")
.all()
)
permission_classes = (
IsAdminUser,
ProductPermissions,
)
search_fields = ("name",)
filterset_class = ProductFilter
def get_serializer_class(self):
if self.action == "create":
return CreateProductSerializer
elif self.action == "list":
return ListProductSerializer
elif self.action in ("update", "partial_update"):
return UpdateProductSerializer
return self.serializer_class
def perform_destroy(self, instance):
try:
super().perform_destroy(instance)
except ProtectedError:
raise ValidationError(_("No se puede borrar el producto"))
class ProductPriceViewSet(ModelViewSet):
serializer_class = ProductPriceSerializer
queryset = ProductPrice.objects.all()
permission_classes = (
IsAdminUser,
ProductPricePermissions,
)
def get_queryset(self):
return super().get_queryset().filter(product_id=self.kwargs.get("product_id"))
def get_serializer_class(self):
if self.action == "create":
return CreateProductPriceSerializer
return self.serializer_class
def perform_create(self, serializer):
product = get_object_or_404(Product, pk=self.kwargs.get("product_id"))
product.prices.all().update(current=False)
serializer.save(product=product, current=True)
class ProductBatchViewSet(ModelViewSet):
serializer_class = ProductBatchSerializer
queryset = ProductBatch.objects.all()
permission_classes = (IsAdminUser,)
def perform_create(self, serializer):
instance = serializer.save()
product = instance.product
product.stock += instance.quantity
product.save()
def perform_destroy(self, instance):
delete_product_batch(instance)
def perform_update(self, serializer):
instance = self.get_object()
product = instance.product
product.stock -= instance.quantity
updated_batch = serializer.save()
product.stock += updated_batch.quantity
product.save()
class CustomerViewSet(ModelViewSet):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
permission_classes = (IsAdminUser,)
class ProviderViewSet(ModelViewSet):
serializer_class = ProviderSerializer
queryset = Provider.objects.all()
permission_classes = (IsAdminUser,)
class TaxViewSet(ModelViewSet):
serializer_class = TaxSerializer
queryset = Tax.objects.all()
permission_classes = (IsAdminUser,)
search_fields = ("code",)
class OrderViewSet(ModelViewSet):
serializer_class = OrderSerializer
queryset = Order.objects.all()
lookup_field = "uuid"
class OrderLineViewSet(ModelViewSet):
serializer_class = OrderLineSerializer
queryset = OrderLine.objects.all()
def perform_create(self, serializer):
with transaction.atomic():
order = get_object_or_404(Order, uuid=self.kwargs.get("order_id"))
product = serializer.validated_data.get("product")
price = product.prices.last()
tax = price.tax.value
quantity = serializer.validated_data.get("quantity")
base_total = quantity * price.price
taxes = base_total * (tax / Decimal("100"))
total = base_total + taxes
instance = serializer.save(
order=order,
price=price.price,
base_total=base_total,
tax_value=tax,
taxes=taxes,
total=total,
)
order.base_total += instance.base_total
order.total += instance.total
order.save()
def perform_destroy(self, instance):
order = instance.order
with transaction.atomic():
order.base_total -= instance.base_total
order.total -= instance.total
instance.delete()
order.save()
def get_queryset(self):
return (
super()
.get_queryset()
.select_related("order")
.filter(order__uuid=self.kwargs.get("order_id"))
)
class TagViewSet(ModelViewSet):
serializer_class = TagSerializer
queryset = Tag.objects.all()
permission_classes = (IsAdminUser,)
class BrandViewSet(ModelViewSet):
serializer_class = BrandSerializer
queryset = Brand.objects.all()
permission_classes = (IsAdminUser,)
search_fields = ("name",)