From 115544f3d33d91315a7ef13757c0f57d00b3a1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o?= Date: Fri, 31 Jan 2025 15:23:57 +0100 Subject: [PATCH] handle multiple products and handling errors, using atomicity need --- StockSeeker/serializers.py | 83 +++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/StockSeeker/serializers.py b/StockSeeker/serializers.py index 4a1b9be..0c47a03 100644 --- a/StockSeeker/serializers.py +++ b/StockSeeker/serializers.py @@ -2,7 +2,7 @@ from rest_framework import serializers from .models import * from django.contrib.auth.models import User from django.db.models import F - +from django.db import transaction class UserSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) @@ -50,38 +50,51 @@ class ProductSerializer(serializers.ModelSerializer): model = Product fields = ["id", "name", "description", "quantity", "creation_date", "modification_date", "user","stock_limit","alert_enabled","is_stock_low","image","warehouses",] - #GERER les nombres négatifs impossible # def create(self, validated_data): warehouses = validated_data.pop('warehouses', []) - product = Product.objects.create(**validated_data) - product.warehouses.set(warehouses) + + with transaction.atomic(): + product = Product.objects.create(**validated_data) + product.warehouses.set(warehouses) - for warehouse in product.warehouses.all(): - warehouse.actual_capacity = F('actual_capacity') - product.quantity - warehouse.save(update_fields=['actual_capacity']) + for warehouse in product.warehouses.all(): + warehouse.refresh_from_db() + if warehouse.actual_capacity - product.quantity < 0: + raise serializers.ValidationError({ + 'quantity': ["L'entrepôt n'a plus assez de place"] + }) + warehouse.actual_capacity = F('actual_capacity') - product.quantity + warehouse.save(update_fields=['actual_capacity']) return product def update(self,instance, validated_data): - instance.name = validated_data.get("name", instance.name) - instance.description = validated_data.get("description", instance.description) new_quantity = validated_data.get("quantity", instance.quantity) - quantity_difference = new_quantity - instance.quantity - instance.quantity = new_quantity - instance.save() - instance.refresh_from_db() - for warehouse in instance.warehouses.all(): - warehouse.actual_capacity = F('actual_capacity') - quantity_difference - warehouse.save(update_fields=['actual_capacity']) - return instance + with transaction.atomic(): + instance.name = validated_data.get("name", instance.name) + instance.description = validated_data.get("description", instance.description) + instance.quantity = new_quantity + instance.save() + + for warehouse in instance.warehouses.all(): + warehouse.refresh_from_db() + if warehouse.actual_capacity - quantity_difference < 0: + raise serializers.ValidationError({ + 'quantity': ["L'entrepôt n'a plus assez de place"] + }) + warehouse.actual_capacity = F('actual_capacity') - quantity_difference + warehouse.save(update_fields=['actual_capacity']) + return instance def destroy(self, instance): - for warehouse in instance.warehouses.all(): - warehouse.actual_capacity = F('actual_capacity') + instance.quantity - warehouse.save(update_fields=['actual_capacity']) - instance.delete() + with transaction.atomic(): + for warehouse in instance.warehouses.all(): + warehouse.refresh_from_db() + warehouse.actual_capacity = F('actual_capacity') + instance.quantity + warehouse.save(update_fields=['actual_capacity']) + instance.delete() def validate_warehouses(self, value): if not value: @@ -102,16 +115,25 @@ class WarehouseSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): old_max_capacity = instance.max_capacity - instance.name = validated_data.get("name", instance.name) - instance.location = validated_data.get("location", instance.location) - new_max_capacity = validated_data.get("max_capacity", instance.max_capacity) - capacity_difference = new_max_capacity - old_max_capacity - instance.actual_capacity = F('actual_capacity') + capacity_difference - instance.max_capacity = new_max_capacity + with transaction.atomic(): + instance.name = validated_data.get("name", instance.name) + instance.location = validated_data.get("location", instance.location) + new_max_capacity = validated_data.get("max_capacity", instance.max_capacity) - instance.save() - instance.refresh_from_db() + capacity_difference = new_max_capacity - old_max_capacity + + new_actual_capacity = instance.actual_capacity + capacity_difference + if new_actual_capacity < 0: + raise serializers.ValidationError({ + 'max_capacity': ["La réduction de la capacité maximale entraînerait une capacité actuelle négative."] + }) + + instance.actual_capacity = F('actual_capacity') + capacity_difference + instance.max_capacity = new_max_capacity + + instance.save() + instance.refresh_from_db() return instance @@ -119,6 +141,9 @@ class WarehouseSerializer(serializers.ModelSerializer): model = Warehouse fields = ["id", "name", "location", "max_capacity","user","actual_capacity"] + def create(self, validated_data): + validated_data["actual_capacity"] = validated_data.get("max_capacity",0) + return Warehouse.objects.create(**validated_data) def validate_max_capacity(self, value): if value < 0: