Implement non-destructive order updates
This commit is contained in:
parent
89e853b490
commit
d47c94ba84
3 changed files with 30 additions and 1 deletions
|
@ -827,6 +827,7 @@ class Order(models.Model):
|
|||
editable=False)
|
||||
billing_address = models.ForeignKey(BillingAddress, on_delete=models.CASCADE)
|
||||
description = models.TextField()
|
||||
replaced_by = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True)
|
||||
|
||||
# TODO: enforce ending_date - starting_date to be larger than recurring_period.
|
||||
creation_date = models.DateTimeField(auto_now_add=True)
|
||||
|
|
|
@ -71,7 +71,7 @@ class OrderSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = Order
|
||||
fields = ['uuid', 'owner', 'description', 'creation_date', 'starting_date', 'ending_date',
|
||||
'bill', 'recurring_period', 'recurring_price', 'one_time_price']
|
||||
'bill', 'recurring_period', 'recurring_price', 'one_time_price', 'replaced_by']
|
||||
|
||||
|
||||
###
|
||||
|
|
|
@ -13,6 +13,7 @@ from hardcopy import bytestring_to_pdf
|
|||
from django.core.files.temp import NamedTemporaryFile
|
||||
from django.http import FileResponse
|
||||
from django.template.loader import render_to_string
|
||||
from copy import deepcopy
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
@ -304,6 +305,7 @@ class AdminBillViewSet(BillViewSet):
|
|||
class AdminOrderViewSet(mixins.ListModelMixin,
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.CreateModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
viewsets.GenericViewSet):
|
||||
serializer_class = OrderSerializer
|
||||
permission_classes = [permissions.IsAdminUser]
|
||||
|
@ -314,6 +316,32 @@ class AdminOrderViewSet(mixins.ListModelMixin,
|
|||
def get_queryset(self):
|
||||
return Order.objects.all()
|
||||
|
||||
# Updates create a new order and terminate the 'old' one.
|
||||
@transaction.atomic
|
||||
def update(self, request, *args, **kwargs):
|
||||
order = self.get_object()
|
||||
partial = kwargs.pop('partial', False)
|
||||
serializer = self.get_serializer(order, data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
# Clone existing order for replacement.
|
||||
replacing_order = deepcopy(order)
|
||||
|
||||
# Yes, that's how you make a new entry in DB:
|
||||
# https://docs.djangoproject.com/en/3.0/topics/db/queries/#copying-model-instances
|
||||
replacing_order.pk = None
|
||||
|
||||
for attr, value in serializer.validated_data.items():
|
||||
setattr(replacing_order, attr, value)
|
||||
|
||||
# Save replacing order and terminate 'previous' one.
|
||||
replacing_order.save()
|
||||
order.replaced_by = replacing_order
|
||||
order.save()
|
||||
order.terminate()
|
||||
|
||||
return Response(replacing_order)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def terminate(self, request, pk):
|
||||
order = self.get_object()
|
||||
|
|
Loading…
Reference in a new issue