Skip to content

Commit 73e43ae

Browse files
committed
change in order mdoel
1 parent 22c93da commit 73e43ae

File tree

11 files changed

+199
-232
lines changed

11 files changed

+199
-232
lines changed

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"sqltools.connections": [
3+
{
4+
"previewLimit": 50,
5+
"server": "postgres",
6+
"port": 5432,
7+
"driver": "PostgreSQL",
8+
"name": "wine_store",
9+
"database": "wine_store",
10+
"username": "SvuCYfHrKizkDqgiPnEJGDOYXmPRBOgU",
11+
"password": "wPKS5SuYFMcABMA7dILvGrrxtgRG4DUELDCcMFxw1ERTZnmMkDXDMVayXHh6dbak"
12+
}
13+
]
14+
}

local.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ services:
3333
- wine_store_local_postgres_data_backups:/backups
3434
env_file:
3535
- ./.envs/.local/.postgres
36+
ports:
37+
- '5432:5432'
3638

3739
docs:
3840
image: wine_store_local_docs

wine_store/orders/api/serializers.py

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@
22
Order Serializers
33
"""
44

5+
import hashlib
6+
from random import randint
7+
8+
# Utils
9+
from time import sleep
10+
511
# Rest Framework
6-
from rest_framework.serializers import ModelSerializer
12+
from rest_framework import serializers
13+
14+
# Cart
15+
from wine_store.cart.api.serializers import CartModelSerializer
16+
from wine_store.cart.models import CartItem
717

818
# Order
9-
from wine_store.orders.models import OrderDetail
19+
from wine_store.orders.models import OrderDetail, OrderItem, OrderPayment
20+
from wine_store.users.api.serializers import UserAddressModelSerializer
1021

22+
# User
23+
from wine_store.users.models import UserAddress, UserPayment
1124

12-
class OrderSerializer(ModelSerializer):
25+
26+
class OrderModelSerializer(serializers.ModelSerializer):
1327
"""Order serializer."""
1428

1529
class Meta:
@@ -18,3 +32,119 @@ class Meta:
1832
model = OrderDetail
1933
fields = "__all__"
2034
read_only_fields = ["user", "total", "order_status", "created_at", "updated_at"]
35+
36+
37+
class OrderItemModelSerializer(serializers.ModelSerializer):
38+
"""Order item serializer."""
39+
40+
class Meta:
41+
"""Meta options."""
42+
43+
model = OrderItem
44+
fields = "__all__"
45+
read_only_fields = ["order_detail", "product", "quantity", "price"]
46+
47+
48+
class OrderPaymentModelSerializer(serializers.ModelSerializer):
49+
"""Order payment serializer."""
50+
51+
class Meta:
52+
"""Meta options."""
53+
54+
model = OrderPayment
55+
fields = "__all__"
56+
read_only_fields = ["order_detail", "total", "payment_method"]
57+
58+
59+
class OrderReadModelSerializer(serializers.ModelSerializer):
60+
"""Order Detail read serializer."""
61+
62+
user = serializers.StringRelatedField()
63+
shipping_address = UserAddressModelSerializer(many=False, read_only=True)
64+
payment = OrderPaymentModelSerializer(many=False, read_only=True)
65+
items = OrderItemModelSerializer(many=True, read_only=True)
66+
67+
class Meta:
68+
"""Meta options."""
69+
70+
model = OrderDetail
71+
fields = "__all__"
72+
read_only_fields = ["user", "total", "order_status", "created_at", "updated_at"]
73+
74+
75+
class OrderSerializer(serializers.Serializer):
76+
"""Order serializer."""
77+
78+
shipping_address = serializers.IntegerField()
79+
payment_method = serializers.IntegerField()
80+
cart = CartModelSerializer(many=False, write_only=True)
81+
82+
def validate_shipping_address(self, value):
83+
try:
84+
user_address = UserAddress.objects.get(id=value)
85+
return user_address
86+
except UserAddress.DoesNotExist:
87+
raise serializers.ValidationError("The user address does not exist")
88+
89+
def validate_payment_method(self, value):
90+
try:
91+
user_payment = UserPayment.objects.get(id=value)
92+
return user_payment
93+
except UserPayment.DoesNotExist:
94+
raise serializers.ValidationError("The user payment does not exist")
95+
96+
def validate(self, data):
97+
items = CartItem.objects.filter(cart=data["cart"])
98+
if len(items) == 0:
99+
raise serializers.ValidationError("The cart is empty")
100+
self.context["items"] = items
101+
data["total"] = 0
102+
data["order_status"] = "PENDING"
103+
return data
104+
105+
def create(self, validated_data):
106+
"""Create order."""
107+
user_payment = validated_data.pop("user_payment")
108+
# Create order detail
109+
order = OrderDetail.objects.create(**validated_data)
110+
# Create order items
111+
items = self.context["items"]
112+
for item in items:
113+
OrderItem.objects.create(
114+
order_detail=order,
115+
product=item.product,
116+
quantity=item.quantity,
117+
price=item.price,
118+
)
119+
# making payment
120+
order.total = order.calculate_total()
121+
order.save()
122+
payment_status, payment_register = self.make_request_payment(user_payment, order.total)
123+
OrderPayment.objects.create(
124+
order_detail=order,
125+
total=order.total,
126+
payment_method=user_payment,
127+
payment_register=payment_register,
128+
payment_status=payment_status,
129+
)
130+
131+
return order
132+
133+
def update(self, instance, validated_data):
134+
"""Update order."""
135+
pass
136+
137+
def make_request_payment(self, user_payment, total):
138+
"""Make request payment.
139+
This is a function simulate the interaction with a payment gateway.
140+
"""
141+
sleep(5)
142+
success_flag = True if randint(0, 10) < 8 else False
143+
if success_flag:
144+
sha_payment = hashlib.sha256(
145+
f"{user_payment.id}+{user_payment.provider}+{user_payment.payment_method}+{total}".encode()
146+
)
147+
payment_register = sha_payment.hexdigest()
148+
return ("SUCCESS", payment_register)
149+
else:
150+
return ("FAILED", None)

wine_store/orders/api/views.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,45 @@
66
import logging
77

88
# Rest Framework
9-
from rest_framework import status
109
from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin
1110
from rest_framework.permissions import IsAuthenticated
12-
from rest_framework.response import Response
1311
from rest_framework.viewsets import GenericViewSet
1412

1513
# Cart
16-
from wine_store.cart.models import Cart, CartItem
17-
from wine_store.orders.api.serializers import OrderSerializer
14+
from wine_store.cart.models import Cart
15+
from wine_store.orders.api.serializers import OrderReadModelSerializer, OrderSerializer
1816

1917
# Orders
20-
from wine_store.orders.models import OrderDetail, OrderItem, OrderPayment
21-
22-
# Users
23-
from wine_store.users.models import UserPayment
18+
from wine_store.orders.models import OrderDetail
2419

2520
# Utils
2621
from wine_store.utils.permissions import IsOwner
2722

23+
# Users
24+
25+
2826
logger = logging.getLogger(__name__)
2927

3028

3129
class OrderViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericViewSet):
3230
"""Order view set."""
3331

34-
serializer_class = OrderSerializer
3532
permission_classes = [IsAuthenticated, IsOwner]
3633

34+
def get_serializer_class(self):
35+
"""Return serializer based on action."""
36+
if self.action == "retrieve" or self.action == "list":
37+
return OrderReadModelSerializer
38+
return OrderSerializer
39+
3740
def get_queryset(self):
3841
"""Return orders for current user."""
3942
orders = OrderDetail.objects.filter(user=self.request.user)
4043
return orders
4144

4245
def perform_create(self, serializer):
43-
"""Create a new order."""
44-
cart = Cart.objects.get(id=self.request.user.cart.id)
45-
if cart.items.count() == 0:
46-
return Response(status=status.HTTP_400_BAD_REQUEST)
47-
48-
order_detail = serializer.save(user=self.request.user, total=cart.total, order_status="processing")
49-
# Create order items
50-
cart_items = CartItem.objects.filter(cart=cart)
51-
total = 0.0
52-
for cart_item in cart_items:
53-
OrderItem.objects.create(
54-
order_detail=order_detail,
55-
product=cart_item.product,
56-
quantity=cart_item.quantity,
57-
price=cart_item.product.price,
58-
)
59-
total += +float(cart_item.product.price) * float(cart_item.quantity)
60-
61-
if total != float(cart.total):
62-
logger.error("Total of order is not equal to total of cart")
63-
64-
payment_method_id = self.request.data.get("payment_method_id")
65-
payment = UserPayment.objects.get(id=payment_method_id)
66-
67-
# Create order payment
68-
OrderPayment.objects.create(
69-
order_detail=order_detail,
70-
payment_method=payment,
71-
total=total,
72-
payment_status="pending",
73-
payment_register=f"O-id-{order_detail.id}-{payment.provider}-{payment.payment_method}",
74-
)
75-
# Delete cart
46+
"""Create order."""
47+
cart = Cart.objects.get(user=self.request.user)
48+
serializer.save(user=self.request.user, cart=cart)
7649
cart.delete()
77-
# create new cart
7850
Cart.objects.create(user=self.request.user)

wine_store/orders/migrations/0001_initial.py

Lines changed: 0 additions & 60 deletions
This file was deleted.

wine_store/orders/migrations/0002_initial.py

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)