Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions order/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ def get_orders_by_reformer(self, user: User = None):
.select_related("service", "service__market", "service__market__reformer")
.filter(service__market__reformer__user=user)
)


class OrderStatusManager(models.Manager):

def get_order_status_by_order_uuid(self, order_uuid: str):
return (
super()
.get_queryset()
.select_related("order")
.filter(order__order_uuid=order_uuid)
)
23 changes: 21 additions & 2 deletions order/mixins.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
from datetime import date, timedelta
from typing import Any, override
from datetime import date
from typing import Any, Optional, override

from django.db.models import QuerySet
from rest_framework.exceptions import ValidationError

from core.mixins import QueryParamMixin
from order.models import _OrderStatus


class OrderStatusQueryParamMixin(QueryParamMixin):

def __init__(self):
super().__init__()
self.ALLOWED_FILTER_ARRAY = [choice[0] for choice in _OrderStatus.choices]

@override
def apply_filters_and_sorting(
self, queryset: QuerySet, status: Optional[str]
) -> QuerySet:
if status:
if status not in self.ALLOWED_FILTER_ARRAY:
raise ValidationError("Invalid status query parameter")
return queryset.filter(status=status)
else:
return queryset


class OrderQueryParamMinxin(QueryParamMixin):
Expand Down
4 changes: 3 additions & 1 deletion order/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.db import models

from core.models import TimeStampedModel
from order.managers import OrderManager
from order.managers import OrderManager, OrderStatusManager


def get_order_image_upload_path(instance, filename):
Expand Down Expand Up @@ -96,6 +96,8 @@ class OrderStatus(TimeStampedModel):
default="pending",
)

objects = OrderStatusManager()

class Meta:
db_table = "order_status"

Expand Down
7 changes: 2 additions & 5 deletions order/serializers/order_retrieve_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@
from order.models import Order
from order.serializers.delivery_status_serializer import DeliveryStatusSerializer
from order.serializers.order_create_serializer import OrderImageSerializer
from order.serializers.order_status_serializer import OrderStatusSerailzier
from order.serializers.order_status_serializer import OrderStatusRetrieveSerializer
from order.serializers.orderer_information_serializer import (
OrdererInformationSerializer,
)
from order.serializers.transaction_serializer import TransactionSerializer
from users.serializers.reformer_serializer.reformer_profile_serializer import (
ReformerProfileSerializer,
)
from users.serializers.user_serializer.user_information_serializer import (
UserOrderInformationSerializer,
)
Expand All @@ -29,7 +26,7 @@ class OrderRetrieveSerializer(serializers.ModelSerializer):
service_info = serializers.SerializerMethodField(read_only=True)
materials = ServiceMaterialRetrieveSerializer(many=True, read_only=True)
additional_options = ServiceOptionRetrieveSerializer(many=True, read_only=True)
order_status = OrderStatusSerailzier(many=True, read_only=True)
order_status = OrderStatusRetrieveSerializer(many=True, read_only=True)
orderer_information = serializers.SerializerMethodField(read_only=True)
transaction = TransactionSerializer(read_only=True)
delivery_status = serializers.SerializerMethodField(read_only=True)
Expand Down
14 changes: 13 additions & 1 deletion order/serializers/order_status_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@
from order.models import OrderStatus


class OrderStatusSerailzier(serializers.ModelSerializer):
class OrderStatusRetrieveSerializer(serializers.ModelSerializer):

class Meta:
model = OrderStatus
fields = ["status", "created"]


class OrderStatusRejectedSerailzier(serializers.ModelSerializer):
rejected_reason = serializers.SerializerMethodField(read_only=True)

def get_rejected_reason(self, obj):
return obj.order.rejected_reason

class Meta:
model = OrderStatus
fields = ["status", "rejected_reason", "created"]
62 changes: 62 additions & 0 deletions order/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,68 @@ def test_update_order_status_invalid_status(self):

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

def test_get_rejceted_order_status_with_order_uuid(self):
# Given
# 주문 1개 생성
self.generate_order(num=1)
self.assertEqual(Order.objects.all().count(), 1)
order = Order.objects.all().first()

# update order status update to reject
response = self.reformer_client.patch(
path=f"/api/orders/{str(order.order_uuid)}/status",
data={"status": "rejected", "rejected_reason": "this is test"},
format="json",
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
order.refresh_from_db()
self.assertEqual(order.order_status.first().status, "rejected")
self.assertEqual(order.rejected_reason, "this is test")

# When
response = self.user_client.get(
path=f"/api/orders/{str(order.order_uuid)}/status",
query_params={"filter": "rejected"},
format="json",
)

# Then
order_status: OrderStatus = order.order_status.first()
self.assertEqual(order_status.status, response.data.get("status"))
self.assertEqual(order.rejected_reason, response.data.get("rejected_reason"))
self.assertIn("created", response.data)

def test_get_order_status_with_order_uuid(self):
# Given
# 주문 1개 생성
self.generate_order(num=1)
self.assertEqual(Order.objects.all().count(), 1)
order = Order.objects.all().first()

# update order status update to received
response = self.reformer_client.patch(
path=f"/api/orders/{str(order.order_uuid)}/status",
data={"status": "received"},
format="json",
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
order.refresh_from_db()
self.assertEqual(order.order_status.first().status, "received")

# When
response = self.user_client.get(
path=f"/api/orders/{str(order.order_uuid)}/status",
query_params={"filter": "received"},
format="json",
)

# Then
order_status: OrderStatus = order.order_status.first()
self.assertEqual(order_status.status, response.data.get("status"))
self.assertIn("created", response.data)

def tearDown(self):
patch.stopall() # 활성화된 Mocking 중단
Order.objects.all().delete()
2 changes: 1 addition & 1 deletion order/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
),
path(
"/<uuid:order_uuid>/status",
OrderStatusUpdateView.as_view(),
OrderStatusView.as_view(),
name="order_update",
),
path(
Expand Down
46 changes: 38 additions & 8 deletions order/views/order_view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from typing import Optional

from django.core.exceptions import ObjectDoesNotExist
from django.db.models.query import QuerySet
Expand All @@ -10,7 +11,7 @@
from core.exceptions import view_exception_handler
from core.permissions import IsReformer
from market.models import Service
from order.mixins import OrderQueryParamMinxin
from order.mixins import OrderQueryParamMinxin, OrderStatusQueryParamMixin
from order.models import DeliveryInformation, Order, OrderStatus, _OrderStatus
from order.pagination import OrderListPagination
from order.serializers.delivery_status_serializer import DeliveryStatusSerializer
Expand All @@ -19,6 +20,10 @@
OrderCreateSerializer,
)
from order.serializers.order_retrieve_serializer import OrderRetrieveSerializer
from order.serializers.order_status_serializer import (
OrderStatusRejectedSerailzier,
OrderStatusRetrieveSerializer,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -67,14 +72,10 @@ def get(self, request):

@view_exception_handler
def post(self, request):
logger.debug("POST : /api/orders")
logger.debug(request.data)

serializer: OrderCreateSerializer = OrderCreateSerializer(
data=request.data, context={"request": request}
)
serializer.is_valid(raise_exception=True)
logger.debug("serializer 검증 완료 -> save() 호출")
order: Order = serializer.save() # create 호출

response_serializer: OrderCreateResponseSerializer = (
Expand Down Expand Up @@ -104,20 +105,48 @@ def get(self, request, **kwargs):
return Response(data=serializer.data, status=status.HTTP_200_OK)


class OrderStatusUpdateView(APIView):
class OrderStatusView(OrderStatusQueryParamMixin, APIView):
"""
주문 UUID를 사용하여 주문 상태 정보를 업데이트 하는 API 구현체
"""

permission_classes = [IsAuthenticated]

@view_exception_handler
def patch(self, request, **kwargs):
def get(self, request, **kwargs) -> Response:
order_uuid: Optional[str] = kwargs.get("order_uuid", None)
if not order_uuid:
raise ValueError("order_uuid path parameter is required")

_status: Optional[str] = request.GET.get("filter", None)
queryset: QuerySet = OrderStatus.objects.get_order_status_by_order_uuid(
order_uuid=order_uuid
)
order_status: OrderStatus = self.apply_filters_and_sorting(
queryset=queryset, status=_status
).first()

if _status == _OrderStatus.REJECTED:
serializer: OrderStatusRejectedSerailzier = OrderStatusRejectedSerailzier(
instance=order_status
)
else:
serializer: OrderStatusRetrieveSerializer = OrderStatusRetrieveSerializer(
instance=order_status
)
return Response(data=serializer.data, status=status.HTTP_200_OK)

@view_exception_handler
def patch(self, request, **kwargs) -> Response:
order_uuid: Optional[str] = kwargs.get("order_uuid", None)
if not order_uuid:
raise ValueError("order_uuid path parameter is required")

_status: str = request.data.get("status")
if _status is None:
raise ValueError("status query parameter is required")

order: Order = Order.objects.filter(order_uuid=kwargs.get("order_uuid")).first()
order: Order = Order.objects.filter(order_uuid=order_uuid).first()
if not order:
raise ObjectDoesNotExist("order not found")
order_status: OrderStatus = OrderStatus.objects.filter(order=order).first()
Expand All @@ -138,6 +167,7 @@ def patch(self, request, **kwargs):
order_status.status = _OrderStatus.END
case _:
raise ValueError("invalid status query parameter")
order.save()
order_status.save()
return Response(status=status.HTTP_200_OK)

Expand Down
Loading