Files
shoppy/shop/api/v1/viewsets.py
T
2024-05-18 13:41:02 +02:00

163 lines
4.5 KiB
Python

from decimal import Decimal
from django.db.models.deletion import ProtectedError
from django.utils.text import gettext_lazy as _
from django.shortcuts import get_object_or_404
from django.db import transaction
from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAdminUser
from shop.api.v1.filters import ProductFilter
from shop.api.v1.serializers import (
ProductSerializer,
ProductPriceSerializer,
CustomerSerializer,
TaxSerializer,
OrderSerializer,
OrderLineSerializer,
ProviderSerializer,
ProductBatchSerializer,
CreateProductSerializer,
CreateProductPriceSerializer,
TagSerializer,
ListProductSerializer, UpdateProductSerializer,
)
from shop.models import (
Product,
ProductPrice,
Customer,
Tax,
Order,
OrderLine,
Provider,
ProductBatch,
Tag,
)
from shop.api.v1.permissions import ProductPermissions, ProductPricePermissions
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):
serializer.save(product_id=self.kwargs.get("product_id"))
class ProductBatchViewSet(ModelViewSet):
serializer_class = ProductBatchSerializer
queryset = ProductBatch.objects.all()
class CustomerViewSet(ModelViewSet):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
class ProviderViewSet(ModelViewSet):
serializer_class = ProviderSerializer
queryset = Provider.objects.all()
class TaxViewSet(ModelViewSet):
serializer_class = TaxSerializer
queryset = Tax.objects.all()
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()