Skip to content

Commit 66ac108

Browse files
Testcase written for order fullfillment
1 parent 4156002 commit 66ac108

File tree

7 files changed

+521
-0
lines changed

7 files changed

+521
-0
lines changed

nxtbn/core/enum_perms.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class PermissionsEnum(models.TextChoices):
99
CAN_DELIVER_ORDER = "can_deliver_order"
1010
CAN_UPDATE_ORDER_PYMENT_TERM = "can_update_order_payment_term"
1111
CAN_UPDATE_ORDER_PAYMENT_METHOD = "can_update_order_payment_method"
12+
CAN_FULLFILL_ORDER = "can_fullfill_order" # Directly fullfill order, will not check lifecycle
13+
1214

1315
CAN_INITIATE_PAYMENT_REFUND = "CAN_INITIATE_PAYMENT_REFUND"
1416

nxtbn/order/api/dashboard/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
path('create-customer/', order_views.CreateCustomAPIView.as_view(), name='create-customer'),
1111
path('orders/<uuid:alias>/', order_views.OrderDetailView.as_view(), name='order-detail'),
1212
path('orders/status/update/<uuid:alias>/', order_views.OrderStatusUpdateAPIView.as_view(), name='order-status-update'),
13+
path('orders/fulfill/<uuid:alias>/', order_views.OrderMarkAsFullfiledAPIView.as_view(), name='order-fulfillment-status-update'),
1314
path('orders/payment-term/update/<uuid:alias>/', order_views.OrderPaymentTermUpdateAPIView.as_view(), name='order-payment-term-update'),
1415
path('orders/payment-method/update/<uuid:alias>/', order_views.OrderPaymentMethodUpdateAPIView.as_view(), name='order-payment-method-update'),
1516
path('orders/return-request/', order_views.ReturnRequestAPIView.as_view(), name='return-request'),

nxtbn/order/api/dashboard/views.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from rest_framework.views import APIView
1111
from django.db.models import Sum, Count, F
12+
from django.db import transaction
1213
from django.db.models.functions import TruncMonth, TruncDay, TruncWeek, TruncHour
1314

1415
from django.utils import timezone
@@ -40,6 +41,9 @@
4041

4142
from calendar import monthrange, day_name
4243
from nxtbn.warehouse.utils import adjust_stocks_returned_items
44+
from nxtbn.warehouse.utils import deduct_reservation_on_packed_for_dispatch, release_stock
45+
from nxtbn.order import OrderStockReservationStatus, ReturnReceiveStatus
46+
4347

4448

4549

@@ -445,6 +449,35 @@ def check_permissions(self, request):
445449
code='permission_denied'
446450
)
447451

452+
class OrderMarkAsFullfiledAPIView(generics.GenericAPIView):
453+
queryset = Order.objects.all()
454+
serializer_class = OrderStatusUpdateSerializer
455+
permission_classes = (GranularPermission, )
456+
required_perm = PermissionsEnum.CAN_FULLFILL_ORDER
457+
458+
def patch(self, request, *args, **kwargs):
459+
with transaction.atomic():
460+
instance = Order.objects.get(alias=kwargs['alias'])
461+
462+
if instance.status == OrderStatus.DELIVERED:
463+
raise ValidationError("Order is already marked as fulfilled.")
464+
465+
if instance.status == OrderStatus.CANCELLED:
466+
raise ValidationError("Cannot mark a cancelled order as fulfilled.")
467+
468+
if instance.status == OrderStatus.RETURNED:
469+
raise ValidationError("Cannot mark a returned order as fulfilled.")
470+
471+
# Now check stock and reservation
472+
if instance.reservation_status == OrderStockReservationStatus.DISPATCHED: # do nothing if already dispatched
473+
pass
474+
else:
475+
deduct_reservation_on_packed_for_dispatch(instance)
476+
477+
instance.status = OrderStatus.DELIVERED
478+
instance.save()
479+
return Response({"message": "Order marked as fulfilled."}, status=status.HTTP_200_OK)
480+
448481
class OrderPaymentTermUpdateAPIView(generics.UpdateAPIView):
449482
model = Order
450483
permission_classes = (GranularPermission, )
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Generated by Django 4.2.11 on 2025-02-20 14:31
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("order", "0038_alter_order_reservation_status"),
10+
]
11+
12+
operations = [
13+
migrations.AlterModelOptions(
14+
name="order",
15+
options={
16+
"ordering": ("-created_at",),
17+
"permissions": [
18+
("can_approve_order", "Can approve order"),
19+
("can_cancel_order", "Can cancel order"),
20+
("can_ship_order", "Can ship order"),
21+
("can_pack_order", "Can process order"),
22+
("can_deliver_order", "Can deliver order"),
23+
("can_update_order_payment_term", "Can update order payment term"),
24+
(
25+
"can_update_order_payment_method",
26+
"Can update order payment method",
27+
),
28+
("can_fullfill_order", "Can fullfill order"),
29+
],
30+
},
31+
),
32+
]

nxtbn/order/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ class Meta:
258258
(PermissionsEnum.CAN_DELIVER_ORDER, 'Can deliver order'),
259259
(PermissionsEnum.CAN_UPDATE_ORDER_PYMENT_TERM, 'Can update order payment term'),
260260
(PermissionsEnum.CAN_UPDATE_ORDER_PAYMENT_METHOD, 'Can update order payment method'),
261+
(PermissionsEnum.CAN_FULLFILL_ORDER, 'Can fullfill order'), # Directly fullfill order, will not check order lifecycle
261262
]
262263

263264
def save(self, *args, **kwargs):

0 commit comments

Comments
 (0)