198 lines
5.5 KiB
Python
198 lines
5.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,
|
|
BrandSerializer,
|
|
)
|
|
from shop.models import (
|
|
Product,
|
|
ProductPrice,
|
|
Customer,
|
|
Tax,
|
|
Order,
|
|
OrderLine,
|
|
Provider,
|
|
ProductBatch,
|
|
Tag,
|
|
Brand,
|
|
)
|
|
|
|
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):
|
|
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):
|
|
product = instance.product
|
|
product.stock = max(product.stock - instance.quantity, 0)
|
|
product.save()
|
|
instance.delete()
|
|
|
|
|
|
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",)
|