129 lines
5 KiB
Python
129 lines
5 KiB
Python
from django.core.mail import EmailMessage, EmailMultiAlternatives
|
|
from django.shortcuts import render
|
|
from django.template.loader import render_to_string
|
|
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 = EmailMultiAlternatives(
|
|
subject=f"Order {order.name} from Zapatos Bernini",
|
|
from_email=settings.EMAIL_HOST_USER,
|
|
to=[order.sold_to.email],
|
|
reply_to=[settings.EMAIL_HOST_USER],
|
|
)
|
|
mail.attach_alternative(
|
|
render_to_string(
|
|
template_name="order_sold.html",
|
|
context={"order": order},
|
|
),
|
|
mimetype="text/html",
|
|
)
|
|
mail.attach(
|
|
filename=f"Bernini order {order.name}.csv",
|
|
content=order.as_csv(),
|
|
mimetype="text/csv",
|
|
)
|
|
for line in order.saleorderline_set.all():
|
|
mail.attach(
|
|
filename=f"Bernini order {order.name}/{line.name}.csv",
|
|
content=line.as_csv(),
|
|
mimetype="text/csv",
|
|
)
|
|
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]
|