bernini/order/views.py
2021-01-25 02:27:02 +01:00

113 lines
4.3 KiB
Python

from django.core.mail import EmailMessage
from django.shortcuts import render
from rest_framework import viewsets, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from bernini import settings
from order.models import SaleOrder, SaleOrderLine, Product
from order.serializers import (
SaleOrderSerializer,
SaleOrderLineSerializer,
ProductSerializer,
)
class SaleOrderViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows orders to be viewed or edited. A `SaleOrder` object will render the general sale
document that wraps n products a client can buy, using an intermediate model called `SaleOrderLine`, this means:
a `SaleOrder` object does not interact directly with a product, a `SaleOrderLine` is just a wrap of a product,
which holds its price-per-unit value, and a quantity for that product; lastly, on the other hand, a `SaleOrder`
object will hold the total information by doing a sum() operation with all the lines
"""
queryset = SaleOrder.objects.all().order_by("name")
serializer_class = SaleOrderSerializer
permission_classes = [permissions.IsAuthenticated]
def update(self, request, pk=None, *args, **kwargs):
order: SaleOrder = self.get_object()
for field in SaleOrder.ReadonlyMeta.readonly:
if request.data.get(field) != SaleOrderSerializer(order).data[field]:
return Response(
data=f"You can't manually set the field {field}",
status=status.HTTP_400_BAD_REQUEST
)
return super(SaleOrderViewSet, self).update(request, *args, **kwargs)
def partial_update(self, request, pk=None, *args, **kwargs):
order: SaleOrder = self.get_object()
for field in SaleOrder.ReadonlyMeta.readonly:
if request.data.get(field) != SaleOrderSerializer(order).data[field]:
return Response(
data=f"You can't manually set the field {field}",
status=status.HTTP_400_BAD_REQUEST
)
return super(SaleOrderViewSet, self).partial_update(request, *args, **kwargs)
@action(detail=True, name="Get the total amount")
def total(self, request, pk=None):
order: SaleOrder = self.get_object()
return Response({"amount_total": order.amount_total})
@action(detail=True)
def sold(self, request, pk=None):
"""
Try to sell a `SaleOrder` object, this is, the sale will have assigned
the user which is doing this operation, the persistent total attribute
will be set -`total`- and the `sold_at`
:param request:
:param pk:
:return: the object with -possibly- updated values
"""
return Response(
SaleOrderSerializer(
self.get_object().sell(request.user), context={"request": request}
).data
)
@action(detail=True)
def sent(self, request, pk=None):
order: SaleOrder = self.get_object()
if order.sold_at and order.sold_to.email and settings.EMAIL_HOST_USER:
mail = EmailMessage(
f'Order {order.name} from Zapatos Bernini',
render(
'order_sold.html',
{
'order': order
},
),
settings.EMAIL_HOST_USER,
[order.sold_to.email],
reply_to=[settings.EMAIL_HOST_USER]
)
mail.send()
return Response(status=status.HTTP_200_OK,
data=f"Email sent! You should receive it at {order.sold_to.email}")
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data="Something went wrong on our end")
class SaleOrderLineViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows orders to be viewed or edited.
"""
queryset = SaleOrderLine.objects.all().order_by("name")
serializer_class = SaleOrderLineSerializer
permission_classes = [permissions.IsAuthenticated]
class ProductViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint that allows orders to be viewed or edited
"""
queryset = Product.objects.all().order_by("name")
serializer_class = ProductSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]