diff --git a/.idea/03-commerce.iml b/.idea/03-commerce.iml
index f602895..c6d616b 100644
--- a/.idea/03-commerce.iml
+++ b/.idea/03-commerce.iml
@@ -16,7 +16,7 @@
-
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0c95c56..5876997 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/account/account.http b/account/account.http
index 6a94851..0cc768f 100644
--- a/account/account.http
+++ b/account/account.http
@@ -1,7 +1,7 @@
GET localhost:8000/api/auth
Content-Type: application/json
Accept: application/json
-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImY0MzkyMDQ1LTRmOTktNDk0NC05ZjNhLThlNGNhZTEzMjk3MCJ9.kmsdiH0zSlYyB-_8mV-sVdE0pDBEJSzszCPyJ5zQHMk
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
###
POST localhost:8000/api/auth/signin
@@ -9,25 +9,37 @@ Content-Type: application/json
Accept: application/json
{
- "email": "user@example.com",
- "password": "!!123123!!"
+ "email": "u4@me.me",
+ "password": "12345678!"
}
+###
+POST localhost:8000/api/auth/signup
+Content-Type: application/json
+Accept: application/json
+
+{
+ "first_name": "rb",
+ "last_name": "rb",
+ "email": "u2@gmail.com",
+ "password1": "1234567!",
+ "password2": "1234567!"
+}
###
GET localhost:8000/api/auth
Content-Type: application/json
Accept: application/json
-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImY0MzkyMDQ1LTRmOTktNDk0NC05ZjNhLThlNGNhZTEzMjk3MCJ9.kmsdiH0zSlYyB-_8mV-sVdE0pDBEJSzszCPyJ5zQHMk
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
###
PUT localhost:8000/api/auth
Content-Type: application/json
Accept: application/json
-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImY0MzkyMDQ1LTRmOTktNDk0NC05ZjNhLThlNGNhZTEzMjk3MCJ9.kmsdiH0zSlYyB-_8mV-sVdE0pDBEJSzszCPyJ5zQHMk
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
{
- "first_name": "Layth",
- "last_name": "Zahid",
+ "first_name": "rb",
+ "last_name": "al",
"phone_number": "077",
"address1": "Anything",
"address2": "",
@@ -40,7 +52,7 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImY0MzkyMDQ1L
POST localhost:8000/api/auth/change-password
Content-Type: application/json
Accept: application/json
-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImY0MzkyMDQ1LTRmOTktNDk0NC05ZjNhLThlNGNhZTEzMjk3MCJ9.kmsdiH0zSlYyB-_8mV-sVdE0pDBEJSzszCPyJ5zQHMk
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
{
"old_password": "string!!",
diff --git a/account/authorization.py b/account/authorization.py
index 661ada1..40c0e4e 100644
--- a/account/authorization.py
+++ b/account/authorization.py
@@ -2,7 +2,7 @@
from django.conf import settings
from django.contrib.auth import get_user_model
-from jose import jwt, JWTError
+from jose import jwt, JWTError
from ninja.security import HttpBearer
User = get_user_model()
diff --git a/account/schemas.py b/account/schemas.py
index 681457b..9338f5a 100644
--- a/account/schemas.py
+++ b/account/schemas.py
@@ -22,13 +22,16 @@ class AccountOut(Schema):
company_name: str = None
company_website: str = None
+
class TokenOut(Schema):
access: str
+
class AuthOut(Schema):
token: TokenOut
account: AccountOut
+
class SigninSchema(Schema):
email: EmailStr
password: str
diff --git a/commerce/commerce.http b/commerce/commerce.http
new file mode 100644
index 0000000..c742cfc
--- /dev/null
+++ b/commerce/commerce.http
@@ -0,0 +1,143 @@
+### Cities ###
+GET localhost:8000/api/addresses/cities
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+###
+GET localhost:8000/api/addresses/cities/e6b4c482-8790-4eb1-9f02-c30154c83ead
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+###
+POST localhost:8000/api/addresses/cities
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+{
+ "name": "someCity"
+}
+
+
+###
+PUT localhost:8000/api/addresses/cities/febb249f-32d4-427d-b817-3e979285c564
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+{
+ "name": "anotherCity"
+}
+
+
+###
+DELETE localhost:8000/api/addresses/cities/05ea76ed-6c1f-4e52-b977-83ec01af92a7
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+
+### Addresses ###
+GET localhost:8000/api/addresses
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+###
+POST localhost:8000/api/addresses
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+{
+ "work_address": true,
+ "address1": "ad1",
+ "address2": "ad2",
+ "city": "423f8087-0f94-4a2e-a000-b666b67f06b5",
+ "phone": 2345
+}
+
+###
+GET localhost:8000/api/addresses/6f062ec4-ab1e-4100-8fc2-a14464bfc1ef
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+
+###
+PUT localhost:8000/api/addresses/6f062ec4-ab1e-4100-8fc2-a14464bfc1ef
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+{
+ "work_address": true,
+ "address1": "ed1",
+ "address2": "ed2",
+ "city": "cf14325f-4f98-4be8-9121-2c91ec240758",
+ "phone": 789786656
+}
+
+
+###
+DELETE localhost:8000/api/addresses/6f062ec4-ab1e-4100-8fc2-a14464bfc1ef
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6ImQ3MDA1YjMxLTc3NDEtNDZlNi05NDFjLTM3YmQ1NWY2ZDM4ZiJ9.uwojP9bFnis3PRIzqG46fEUvlvmXfVLWG6kPUw8AmrU
+
+
+### Orders ###
+GET localhost:8000/api/orders/cart
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+###
+POST localhost:8000/api/orders/add-to-cart
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+{
+ "product_id": "8c64de55-b117-4e81-9698-e97a73ce1d87",
+ "item_qty": 2
+}
+
+
+###
+POST localhost:8000/api/orders/item/09a88a6d-f5b1-4f71-a458-9aa9fa074dad/reduce-quantity
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+###
+POST localhost:8000/api/orders/item/09a88a6d-f5b1-4f71-a458-9aa9fa074dad/increase-quantity
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+###
+DELETE localhost:8000/api/orders/item/09a88a6d-f5b1-4f71-a458-9aa9fa074dad
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+
+###
+POST localhost:8000/api/orders/create-order
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+###
+POST localhost:8000/api/orders/checkout
+Content-Type: application/json
+Accept: application/json
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwayI6IjQ5NzM3NzgxLTQzNmYtNGZjYy1hNTM0LWE0MDcwOTZhYTEyZCJ9.EtvJKtq67XQnjIeuE2sm0QmI8pbpdtB3u3MON3PjjYI
+
+{
+ "note": "anyNote",
+ "address": "6f062ec4-ab1e-4100-8fc2-a14464bfc1ef"
+}
\ No newline at end of file
diff --git a/commerce/controllers.py b/commerce/controllers.py
index a8a551a..ff7a618 100644
--- a/commerce/controllers.py
+++ b/commerce/controllers.py
@@ -1,24 +1,28 @@
-import random
-import string
+import random, string
from typing import List
-
-from django.contrib.auth import get_user_model
from django.db.models import Q
from django.shortcuts import get_object_or_404
from ninja import Router
from pydantic import UUID4
from account.authorization import GlobalAuth
-from commerce.models import Product, Category, City, Vendor, Item, Order, OrderStatus
-from commerce.schemas import ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate
+from account.schemas import SigninSchema
+from commerce.models import Product, Category, City, Vendor, Item, Address, Order, OrderStatus
+from commerce.schemas import ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemCreate, \
+ AddressSchema, AddressOut, CheckoutSchema
+
+from django.contrib.auth import get_user_model, authenticate
+
from config.utils.schemas import MessageOut
+User = get_user_model()
+
+''' Routers '''
products_controller = Router(tags=['products'])
address_controller = Router(tags=['addresses'])
vendor_controller = Router(tags=['vendors'])
order_controller = Router(tags=['orders'])
-User = get_user_model()
@vendor_controller.get('', response=List[VendorOut])
def list_vendors(request):
@@ -58,70 +62,7 @@ def list_products(
return products_qs
-"""
-# product = Product.objects.all().select_related('merchant', 'category', 'vendor', 'label')
- # print(product)
- #
- # order = Product.objects.all().select_related('address', 'user').prefetch_related('items')
-
- # try:
- # one_product = Product.objects.get(id='8d3dd0f1-2910-457c-89e3-1b0ed6aa720a')
- # except Product.DoesNotExist:
- # return {"detail": "Not found"}
- # print(one_product)
- #
- # shortcut_function = get_object_or_404(Product, id='8d3dd0f1-2910-457c-89e3-1b0ed6aa720a')
- # print(shortcut_function)
-
- # print(type(product))
- # print(product.merchant.name)
- # print(type(product.merchant))
- # print(type(product.category))
-
-
-Product <- Merchant, Label, Category, Vendor
-
-Retrieve 1000 Products form DB
-
-products = Product.objects.all()[:1000] (select * from product limit 1000)
-
-for p in products:
- print(p)
-
-for every product, we retrieve (Merchant, Label, Category, Vendor) records
-
-Merchant.objects.get(id=p.merchant_id) (select * from merchant where id = 'p.merchant_id')
-Label.objects.get(id=p.label_id) (select * from merchant where id = 'p.label_id')
-Category.objects.get(id=p.category_id) (select * from merchant where id = 'p.category_id')
-Vendor.objects.get(id=p.vendor_id) (select * from merchant where id = 'p.vendor_id')
-
-4*1000+1
-
-Solution: Eager loading
-
-products = (select * from product limit 1000)
-
-mids = [p1.merchant_id, p2.merchant_id, ...]
-[p1.label_id, p2.label_id, ...]
-.
-.
-.
-
-select * from merchant where id in (mids) * 4 for (label, category and vendor)
-
-4+1
-
-"""
-
-
-@address_controller.get('')
-def list_addresses(request):
- pass
-
-
-# @products_controller.get('categories', response=List[CategoryOut])
-# def list_categories(request):
-# return Category.objects.all()
+""" Cities """
@address_controller.get('cities', response={
@@ -145,6 +86,7 @@ def retrieve_city(request, id: UUID4):
return get_object_or_404(City, id=id)
+# no auth for post in controller
@address_controller.post('cities', response={
201: CitiesOut,
400: MessageOut
@@ -157,7 +99,7 @@ def create_city(request, city_in: CitySchema):
@address_controller.put('cities/{id}', response={
200: CitiesOut,
- 400: MessageOut
+ 404: MessageOut
})
def update_city(request, id: UUID4, city_in: CitySchema):
city = get_object_or_404(City, id=id)
@@ -175,12 +117,74 @@ def delete_city(request, id: UUID4):
return 204, {'detail': ''}
+""" Addresses """
+
+
+@address_controller.get('', response={
+ 200: List[AddressOut],
+ 404: MessageOut
+})
+def list_addresses(request):
+ addresses = Address.objects.all()
+ if addresses:
+ return addresses
+ return 404, {'detail': 'No Addresses Found'}
+
+
+@address_controller.get('/{id}', response={
+ 200: AddressOut,
+ 404: MessageOut
+})
+def retrieve_address(request, id: UUID4):
+ address = get_object_or_404(Address, id=id)
+ return address
+
+
+@address_controller.post('', response={
+ 201: AddressOut,
+ 400: MessageOut
+})
+def create_address(request, address_in: AddressSchema):
+ city_instance = City.objects.get(id=address_in.city)
+ del address_in.city
+ user = get_object_or_404(User, id=request.auth['pk'])
+ address = Address.objects.create(**address_in.dict(), city=city_instance, user=user)
+ address.save()
+ return 201, address
+
+
+@address_controller.put('/{id}', response={
+ 200: AddressOut,
+ 404: MessageOut
+})
+def update_address(request, id: UUID4, new_data: AddressSchema):
+ address = get_object_or_404(Address, id=id)
+ city_instance = City.objects.get(id=new_data.city)
+ new_data.city = city_instance
+ for attr, value in new_data.dict().items():
+ setattr(address, attr, value)
+ address.save()
+ return 200, address
+
+
+@address_controller.delete('/{id}', response={
+ 204: MessageOut
+})
+def delete_address(request, id: UUID4):
+ address = get_object_or_404(Address, id=id)
+ address.delete()
+ return 204, {'detail': ''}
+
+
+""" Orders """
+
+
@order_controller.get('cart', response={
200: List[ItemOut],
404: MessageOut
})
def view_cart(request):
- cart_items = Item.objects.filter(user=User.objects.first(), ordered=False)
+ cart_items = Item.objects.filter(user_id=request.auth['pk'], ordered=False)
if cart_items:
return cart_items
@@ -190,15 +194,15 @@ 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.objects.get(product_id=item_in.product_id, user_id=request.auth['pk'])
item.item_qty += 1
item.save()
except Item.DoesNotExist:
- Item.objects.create(**item_in.dict(), user=User.objects.first())
+ Item.objects.create(**item_in.dict(), user_id=request.auth['pk'])
return 200, {'detail': 'Added to cart successfully'}
@@ -207,7 +211,7 @@ def add_update_cart(request, item_in: ItemCreate):
200: MessageOut,
})
def reduce_item_quantity(request, id: UUID4):
- item = get_object_or_404(Item, id=id, user=User.objects.first())
+ item = get_object_or_404(Item, id=id, user_id=request.auth['pk'])
if item.item_qty <= 1:
item.delete()
return 200, {'detail': 'Item deleted!'}
@@ -217,41 +221,88 @@ def reduce_item_quantity(request, id: UUID4):
return 200, {'detail': 'Item quantity reduced successfully!'}
+@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_id=request.auth['pk'])
+ item.item_qty += 1
+ item.save()
+
+ return 200, {'detail': 'Item quantity increased successfully!'}
+
+
@order_controller.delete('item/{id}', response={
204: MessageOut
})
def delete_item(request, id: UUID4):
- item = get_object_or_404(Item, id=id, user=User.objects.first())
+ item = get_object_or_404(Item, id=id, user_id=request.auth['pk'])
item.delete()
return 204, {'detail': 'Item deleted!'}
-def generate_ref_code():
- return ''.join(random.sample(string.ascii_letters + string.digits, 6))
+def ref_code():
+ return ''.join(random.choices(string.ascii_letters + string.digits, k=6))
-@order_controller.post('create-order', auth=GlobalAuth(), response=MessageOut)
+@order_controller.post('/create-order', response={
+ 200: MessageOut,
+ 400: MessageOut
+})
def create_order(request):
- '''
- * add items and mark (ordered) field as True
- * add ref_number
- * add NEW status
- * calculate the total
- '''
-
- 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()
-
- return {'detail': 'order created successfully'}
+ user = get_object_or_404(User, id=request.auth['pk'])
+ if not Order.objects.filter(ordered=False):
+ order = Order.objects.create(
+ user=user,
+ status=OrderStatus.objects.get(is_default=True),
+ ref_code=ref_code(),
+ ordered=False
+ )
+
+ user_items = Item.objects.filter(user=user).filter(ordered=False)
+ order.items.add(*user_items)
+ order.total = order.order_total
+ user_items.update(ordered=True)
+ order.save()
+ return 200, {'detail': 'created successfully '}
+
+ else:
+ order = Order.objects.filter(user=user, ordered=False)
+ order_items = Order.objects.filter(user=user, ordered=False).values('items__product__id',
+ 'items__item_qty',
+ 'items__product__discounted_price')
+ cart_items = Item.objects.filter(user=user).values('product', 'item_qty')
+ for item_in_cart in list(cart_items):
+ for item_in_order in list(order_items):
+ if item_in_cart['product'] == item_in_order['items__product__id']:
+ item_in_cart['item_qty'] += item_in_order['items__item_qty']
+
+ # if not order.ordered:
+ # item_discounted_price = [li['items__product__discounted_price'] for li in order_items]
+ #
+ # for discount in item_discounted_price:
+ # total_price = sum(item['item_qty'] * discount for item in list(cart_items))
+ #
+ # order.total = order.total_price
+ # order.save()
+
+ return 400, {'detail': 'There is an active order'}
+
+
+@order_controller.post('/checkout', response={
+ 200: MessageOut,
+ 404: MessageOut
+})
+def checkout(request, checkout_info: CheckoutSchema):
+ order_obj = get_object_or_404(Order, user=request.auth['pk'], ordered=False)
+
+ if order_obj:
+ order_obj.note = checkout_info.note
+ order_obj.address = Address.objects.get(id=checkout_info.address)
+ order_obj.status = OrderStatus.objects.get(is_default=False)
+ order_obj.ordered = True
+ order_obj.save()
+ return 200, {'detail': 'checkout done'}
+
+ return 404, {'detail': 'No active orders found'}
diff --git a/commerce/schemas.py b/commerce/schemas.py
index 5d68396..cecf7aa 100644
--- a/commerce/schemas.py
+++ b/commerce/schemas.py
@@ -1,21 +1,13 @@
from typing import List
-
from ninja import ModelSchema, Schema
-from ninja.orm import create_schema
from pydantic import UUID4
-
from commerce.models import Product, Merchant
-
-
-
class UUIDSchema(Schema):
id: UUID4
-# ProductSchemaOut = create_schema(Product, depth=2)
-
class VendorOut(UUIDSchema):
name: str
image: str
@@ -42,10 +34,10 @@ class CategoryOut(UUIDSchema):
class ProductOut(ModelSchema):
- vendor: VendorOut
- label: LabelOut
- merchant: MerchantOut
- category: CategoryOut
+ vendor: VendorOut = None
+ label: LabelOut = None
+ merchant: MerchantOut = None
+ category: CategoryOut = None
class Config:
model = Product
@@ -63,9 +55,6 @@ class Config:
]
-# class ProductManualSchemaOut(Schema):
-# pass
-
class CitySchema(Schema):
name: str
@@ -76,7 +65,6 @@ class CitiesOut(CitySchema, UUIDSchema):
class ItemSchema(Schema):
- # user:
product: ProductOut
item_qty: int
ordered: bool
@@ -91,3 +79,29 @@ class ItemOut(UUIDSchema, ItemSchema):
pass
+class AddressSchema(Schema):
+ work_address: bool
+ address1: str
+ address2: str
+ city: UUID4
+ phone: int
+
+
+# i'll edit this soon #
+
+# class AddressUpdate(Schema):
+# work_address: bool
+# address1: str
+# address2: str
+# city: CitySchema
+# phone: int
+
+
+class AddressOut(AddressSchema, UUIDSchema):
+ city: CitiesOut
+
+
+class CheckoutSchema(Schema):
+ note: str = None
+ address: UUID4
+
diff --git a/config/urls.py b/config/urls.py
index 3851026..5cc2df8 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -18,16 +18,17 @@
from django.urls import path
from ninja import NinjaAPI
+from account.authorization import GlobalAuth
from account.controllers import account_controller
from commerce.controllers import products_controller, address_controller, vendor_controller, order_controller
from config import settings
api = NinjaAPI()
-api.add_router('products', products_controller)
-api.add_router('addresses', address_controller)
-api.add_router('vendors', vendor_controller)
-api.add_router('orders', order_controller)
+# api.add_router('products', products_controller)
+api.add_router('addresses', address_controller, auth=GlobalAuth())
+# api.add_router('vendors', vendor_controller)
+api.add_router('orders', order_controller, auth=GlobalAuth())
api.add_router('auth', account_controller)
urlpatterns = [