server/store/serializers.py (87 lines of code) (raw):
#!/usr/bin/python
#
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from rest_framework import serializers
from store.models import Product, SiteConfig, Testimonial
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = [
"id",
"name",
"description",
"price",
"discount_price",
"active",
"discount_percent",
"discount_saving",
"inventory_count",
"image",
]
class TestimonialSerializer(serializers.ModelSerializer):
class Meta:
model = Testimonial
fields = [
"id",
"product_id",
"reviewer_name",
"reviewer_location",
"rating",
"summary",
"description",
]
class SiteConfigSerializer(serializers.ModelSerializer):
class Meta:
model = SiteConfig
fields = [
"active",
"color_primary",
"color_secondary",
"color_action",
"color_action_text",
"site_name",
"site_name_font",
"site_name_color",
"base_font",
]
class CartPaymentSerializer(serializers.Serializer):
method = serializers.ChoiceField(choices=["collect"])
class CartCustomerSerializer(serializers.Serializer):
email = serializers.EmailField()
class CartItemSerializer(serializers.Serializer):
id = serializers.IntegerField()
countRequested = serializers.IntegerField(required=True)
countFulfilled = serializers.IntegerField(required=False)
def validate(self, data):
try:
product = Product.objects.get(pk=data["id"])
except Product.DoesNotExist:
raise serializers.ValidationError(detail={"status": "product_not_found"})
requested = data["countRequested"]
if product.inventory_count < requested:
data["countFulfilled"] = product.inventory_count
# Log error by writing structured JSON. Can be then used with log-based alerting, metrics, etc.
error_name = "INSUFFICIENT_PRODUCT_ERROR"
print(
json.dumps(
{
"severity": "ERROR",
"error": error_name,
"message": f"{error_name}: A purchase was attempted where there was insufficient inventory to fulfil the order.",
"product": product.id,
"method": "CartItemSerializer.validate()",
"countRequested": data["countRequested"],
"countFulfilled": data["countFulfilled"],
}
)
)
raise serializers.ValidationError(
detail={"status": "insufficient_product", "items": data}
)
else:
data["countFulfilled"] = requested
return data
class CartSerializer(serializers.Serializer):
customer = CartCustomerSerializer(required=True)
payment = CartPaymentSerializer(required=True)
items = CartItemSerializer(many=True)
class CheckoutSerializer(serializers.Serializer):
items = CartItemSerializer(many=True)
status = serializers.CharField()