diff --git a/README.md b/README.md
index 849f5a2..e1e90dc 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,6 @@ Note: don't forget to `makemigrations` and `migrate`
/api/orders/item/{id}/increase-quantity
```
-
* create a create-order endpoint
* this endpoint should satisfy the following
* create a new order
@@ -55,11 +54,9 @@ Note: don't forget to `makemigrations` and `migrate`
* the above API endpoints should satisfy the following
* adding items to the cart are separate from the previous order items
- * check if you have an active order, then the create-order endpoint will check for the matching items (i.e. if you have items in your active order that matches the items in the cart) and instead of adding them to the order, just merge them (add the quantities)
+ * check if you have an active order, then the create-order endpoint will check for the matching items (i.e. if you have items in your active order that matches the items in the cart) and instead of adding them to the order, just merge them (add the quantities)
* you can only have one **active** order
-
-
# Workflow
* user lists the products
@@ -75,8 +72,6 @@ Note: don't forget to `makemigrations` and `migrate`
* user can delete address
* user can checkout (checkout)
-
-
## create order
* add items and mark (ordered) field as True
@@ -84,8 +79,7 @@ Note: don't forget to `makemigrations` and `migrate`
* add NEW status
* calculate the total
-
-## checkout
+## checkout
* if this user has an active order
* add address
@@ -97,3 +91,28 @@ Note: don't forget to `makemigrations` and `migrate`
* create addresses schema
* create crud operations
+
+
+
+
+# Zubaidah's TODO
+
+* [x] `Item Model` => increse-quantity endpoint
+
+```http request
+/api/orders/item/{id}/increase-quantity
+```
+
+* [x] `Address Model` => CRUD operations
+
+```http request
+/api/addresses
+```
+
+* [x] `Order Model` => checkout endpoint
+
+```http request
+/api/orders/checkout
+```
+
+* [x] Bonus
diff --git a/commerce/controllers.py b/commerce/controllers.py
index 389aff6..fd77555 100644
--- a/commerce/controllers.py
+++ b/commerce/controllers.py
@@ -7,14 +7,17 @@
from django.shortcuts import get_object_or_404
from ninja import Router
from pydantic import UUID4
+from django.core.exceptions import ObjectDoesNotExist
-from commerce.models import Product, Category, City, Vendor, Item, Order, OrderStatus
-from commerce.schemas import MessageOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate
+from commerce.models import Address, Product, Category, City, Vendor, Item, Order, OrderStatus
+from commerce.schemas import AddressIn, MessageOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate, AddressesOut, CheckOut
products_controller = Router(tags=['products'])
address_controller = Router(tags=['addresses'])
vendor_controller = Router(tags=['vendors'])
order_controller = Router(tags=['orders'])
+checkout_controller = Router(tags=['checkout'])
+
@vendor_controller.get('', response=List[VendorOut])
@@ -187,17 +190,21 @@ def view_cart(request):
@order_controller.post('add-to-cart', response={
200: MessageOut,
- # 400: MessageOut
+ 400: MessageOut
})
def add_update_cart(request, item_in: ItemCreate):
- try:
- item = Item.objects.get(product_id=item_in.product_id, user=User.objects.first())
- item.item_qty += 1
- item.save()
- except Item.DoesNotExist:
- Item.objects.create(**item_in.dict(), user=User.objects.first())
+ user_items = Item.objects.filter(user=User.objects.first()).filter(ordered=False)
+ #adding items to the cart are separate from the previous order items
+ if not user_items:
+ try:
+ item = Item.objects.get(product_id=item_in.product_id, user=User.objects.first())
+ item.item_qty += 1
+ item.save()
+ except Item.DoesNotExist:
+ Item.objects.create(**item_in.dict(), user=User.objects.first())
- return 200, {'detail': 'Added to cart successfully'}
+ return 200, {'detail': 'Added to cart successfully'}
+ return 400, {'detail': 'You are allready have items'}
@order_controller.post('item/{id}/reduce-quantity', response={
@@ -236,19 +243,116 @@ def create_order(request):
* add NEW status
* calculate the total
'''
-
- order_qs = Order.objects.create(
+ #user can have only one active order
+ user_order = Order.objects.filter(user = User.objects.first()).filter(ordered=True)
+ if not user_order:
+ #print("create")
+ order_qs = Order.objects.create(
user=User.objects.first(),
status=OrderStatus.objects.get(is_default=True),
ref_code=generate_ref_code(),
ordered=False,
)
- user_items = Item.objects.filter(user=User.objects.first()).filter(ordered=False)
- order_qs.items.add(*user_items)
- order_qs.total = order_qs.order_total
- user_items.update(ordered=True)
- order_qs.save()
+ user_items = Item.objects.filter(user=User.objects.first()).filter(ordered=False)
+ #adding items to the cart are separate from the previous order items
+ if not user_items:
+ order_qs.items.add(*user_items)
+ order_qs.total = order_qs.order_total
+ user_items.update(ordered=True)
+ order_qs.save()
+ # merger exciting items to the order
+ else:
+ user_items.item_qty += 1
+ user_items.update(ordered=True)
+ user_items.save()
+ return {'detail': 'Order create and items added successfully'}
+ return {'detail': 'You are allready have order'}
+
+
+
+# increse-quantity endpoint
+@order_controller.post('item/{id}/increase-quantity', response={
+ 200: MessageOut,
+})
+def increase_item_quantity(request, id: UUID4):
+ item = get_object_or_404(Item, id=id, user=User.objects.first())
+ item.item_qty += 1
+ item.save()
+
+ return 200, {'detail': 'Item quantity increased successfully!'}
+
+#addresses CRUD operations
+
+@address_controller.get('addresses', response={
+ 200: List[AddressesOut],
+ 404: MessageOut
+})
+def list_addresses(request):
+ addresses_qs = Address.objects.all()
+
+ if addresses_qs:
+ return addresses_qs
- return {'detail': 'order created successfully'}
+ return 404, {'detail': 'No addresses found'}
+
+
+@address_controller.get('addresses/{id}', response={
+ 200: AddressesOut,
+ 404: MessageOut
+})
+def retrieve_address(request, id: UUID4):
+ return get_object_or_404(Address, id=id)
+
+
+@address_controller.post('addresses', response={
+ 201: AddressesOut,
+ 400: MessageOut
+})
+def create_address(request, address_in: AddressIn):
+ address = Address(**address_in.dict())
+ address.save()
+ return 201, address
+
+
+@address_controller.put('addresses/{id}', response={
+ 200: AddressesOut,
+ 400: MessageOut
+})
+def update_address(request, id: UUID4, address_in: AddressIn):
+ address = get_object_or_404(Address, id=id)
+ for attr, value in address_in.dict().items():
+ setattr(address, attr, value)
+ address.save()
+ return 200, address
+
+
+@address_controller.delete('addresses/{id}', response={
+ 204: MessageOut
+})
+def delete_address(request, id: UUID4):
+ address = get_object_or_404(Address, id=id)
+ address.delete()
+ return 204, {'detail': 'Deleted Successfully'}
+
+
+@checkout_controller.post('checkout', response={
+ 400: MessageOut,
+ 200: CheckOut
+})
+def checkout_create(request, check_out: CheckOut):
+ checkout_obj = get_object_or_404(Order, user=User.objects.first(), ordered = False)
+ for item in checkout_obj.items:
+ if item.item_qty > 0:
+ item.item_qty -= 1
+ item.save()
+
+ if checkout_obj.note:
+ checkout_obj.note = check_out.note
+ checkout_obj.address =check_out.address
+ checkout_obj.ordered = True
+ checkout_obj.update(status ='NEW')
+ checkout_obj.save()
+
+ return 200, {'detail': 'checkout successful'}
diff --git a/commerce/schemas.py b/commerce/schemas.py
index 0944297..85bb978 100644
--- a/commerce/schemas.py
+++ b/commerce/schemas.py
@@ -1,10 +1,9 @@
-from typing import List
-
-from ninja import ModelSchema, Schema
-from ninja.orm import create_schema
+from typing import List, Optional
+from ninja import Schema, ModelSchema, schema
from pydantic import UUID4
-from commerce.models import Product, Merchant
+
+from commerce.models import Product, Merchant, OrderStatus
class MessageOut(Schema):
@@ -91,4 +90,22 @@ class ItemCreate(Schema):
class ItemOut(UUIDSchema, ItemSchema):
pass
-
+
+class AddressesOut(UUIDSchema):
+ work_address: bool
+ address1: str
+ address2: str
+ city: CitiesOut
+ phone: str
+
+class AddressIn(Schema):
+ user_id: str
+ work_address: bool
+ address1: str
+ address2: str
+ city_id: UUID4
+ phone: str
+
+class CheckOut(Schema):
+ note: Optional[str]
+ address: List[AddressesOut]
diff --git a/config/urls.py b/config/urls.py
index fea5e70..c2d89a7 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -18,7 +18,7 @@
from django.urls import path
from ninja import NinjaAPI
-from commerce.controllers import products_controller, address_controller, vendor_controller, order_controller
+from commerce.controllers import products_controller, address_controller, vendor_controller, order_controller, checkout_controller
from config import settings
api = NinjaAPI()
@@ -27,6 +27,7 @@
api.add_router('addresses', address_controller)
api.add_router('vendors', vendor_controller)
api.add_router('orders', order_controller)
+api.add_router('checkout', checkout_controller)
urlpatterns = [
path('admin/', admin.site.urls),