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.serializers import ( ProductSerializer, ProductPriceSerializer, CustomerSerializer, TaxSerializer, OrderSerializer, OrderLineSerializer, ProviderSerializer, ProductBatchSerializer, CreateProductSerializer, CreateProductPriceSerializer, ) from shop.models import ( Product, ProductPrice, Customer, Tax, Order, OrderLine, Provider, ProductBatch, ) from shop.api.v1.permissions import ProductPermissions, ProductPricePermissions class ProductViewSet(ModelViewSet): serializer_class = ProductSerializer queryset = Product.objects.prefetch_related("prices").all() permission_classes = ( IsAdminUser, ProductPermissions, ) def get_serializer_class(self): if self.action == "create": return CreateProductSerializer 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"))