diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/03-commerce.iml b/.idea/03-commerce.iml
deleted file mode 100644
index f602895..0000000
--- a/.idea/03-commerce.iml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
deleted file mode 100644
index f1f4a08..0000000
--- a/.idea/dataSources.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- sqlite.xerial
- true
- org.sqlite.JDBC
- jdbc:sqlite:$PROJECT_DIR$/db.sqlite3
- $ProjectFileDir$
-
-
- file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.34.0/sqlite-jdbc-3.34.0.jar
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
deleted file mode 100644
index 86ee15e..0000000
--- a/.idea/dbnavigator.xml
+++ /dev/null
@@ -1,456 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 6314360..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 0c95c56..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 0de4b85..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/sonarlint/issuestore/1/e/1e9075f5bf079c01ef2c910709e91a497d262080 b/.idea/sonarlint/issuestore/1/e/1e9075f5bf079c01ef2c910709e91a497d262080
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/3/8/3899eaa57c40eb771c98133213ba36b6448c9fff b/.idea/sonarlint/issuestore/3/8/3899eaa57c40eb771c98133213ba36b6448c9fff
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/4/9/496a238a6afa168dbaf6efd37bb459331589579c b/.idea/sonarlint/issuestore/4/9/496a238a6afa168dbaf6efd37bb459331589579c
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/5/6/5672f685b93c26153a807ef6a52ff2a42f198564 b/.idea/sonarlint/issuestore/5/6/5672f685b93c26153a807ef6a52ff2a42f198564
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/5/9/597ed58946079f795070145abd2ba40aaf51a0ae b/.idea/sonarlint/issuestore/5/9/597ed58946079f795070145abd2ba40aaf51a0ae
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/7/a/7a4aaa54a3efb112f8e2592ed1507e33ab6a7b8c b/.idea/sonarlint/issuestore/7/a/7a4aaa54a3efb112f8e2592ed1507e33ab6a7b8c
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/7/a/7a7d33b09c54ec66d8355befd1b7bba3f2dcb442 b/.idea/sonarlint/issuestore/7/a/7a7d33b09c54ec66d8355befd1b7bba3f2dcb442
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/7/b/7bc8a653bcb2d639a49932a5ceac337f728844b4 b/.idea/sonarlint/issuestore/7/b/7bc8a653bcb2d639a49932a5ceac337f728844b4
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/7/c/7c4c5de0ae6801f08fa7c742af850c6198fdb35d b/.idea/sonarlint/issuestore/7/c/7c4c5de0ae6801f08fa7c742af850c6198fdb35d
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/8/1/816a718040e81705eecf3d2ee5661e3df09ee75b b/.idea/sonarlint/issuestore/8/1/816a718040e81705eecf3d2ee5661e3df09ee75b
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/b/8/b81cf84376ffae4f5d23a7f977567a52e49d4e8c b/.idea/sonarlint/issuestore/b/8/b81cf84376ffae4f5d23a7f977567a52e49d4e8c
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/e/a/ea3c42abe4941ad1241819c1d6fbf5bb7bd659be b/.idea/sonarlint/issuestore/e/a/ea3c42abe4941ad1241819c1d6fbf5bb7bd659be
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/f/2/f2bd2292f6ef3fccb4e29b9f652489934d9ddf07 b/.idea/sonarlint/issuestore/f/2/f2bd2292f6ef3fccb4e29b9f652489934d9ddf07
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/sonarlint/issuestore/index.pb b/.idea/sonarlint/issuestore/index.pb
deleted file mode 100644
index 690c582..0000000
--- a/.idea/sonarlint/issuestore/index.pb
+++ /dev/null
@@ -1,40 +0,0 @@
-
-S
-#commerce/migrations/0001_initial.py,5/6/5672f685b93c26153a807ef6a52ff2a42f198564
-B
-config/__init__.py,7/c/7c4c5de0ae6801f08fa7c742af850c6198fdb35d
-C
-account/__init__.py,7/a/7a7d33b09c54ec66d8355befd1b7bba3f2dcb442
-D
-commerce/__init__.py,f/2/f2bd2292f6ef3fccb4e29b9f652489934d9ddf07
->
-config/wsgi.py,7/a/7a4aaa54a3efb112f8e2592ed1507e33ab6a7b8c
->
-config/asgi.py,5/9/597ed58946079f795070145abd2ba40aaf51a0ae
-\
-,.idea/inspectionProfiles/Project_Default.xml,4/9/496a238a6afa168dbaf6efd37bb459331589579c
-@
-account/tests.py,8/1/816a718040e81705eecf3d2ee5661e3df09ee75b
-^
-..idea/inspectionProfiles/profiles_settings.xml,1/e/1e9075f5bf079c01ef2c910709e91a497d262080
-?
-account/apps.py,3/8/3899eaa57c40eb771c98133213ba36b6448c9fff
-N
-account/migrations/__init__.py,7/b/7bc8a653bcb2d639a49932a5ceac337f728844b4
-@
-commerce/apps.py,e/a/ea3c42abe4941ad1241819c1d6fbf5bb7bd659be
-O
-commerce/migrations/__init__.py,b/8/b81cf84376ffae4f5d23a7f977567a52e49d4e8c
-@
-requirements.txt,1/9/19359a61ae2446b51b549167b014da2fcf265768
-A
-commerce/tests.py,5/2/52ea416cfb7f2a70c29e2ed02817ad03d3de8885
-:
-
-.gitignore,a/5/a5cc2925ca8258af241be7e5b0381edf30266302
-A
-commerce/admin.py,d/7/d7369e273d90449ac8ca98014a010a921d984597
-^
-.commerce/migrations/0002_auto_20211027_1637.py,d/a/daa0931328d2da3ea0d7525a016a5059103dbb53
-9
- manage.py,3/1/3156ad13e4d695cd526bbb7b031016ecba842270
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/account/admin.py b/account/admin.py
index 8d07a97..c10a1bb 100644
--- a/account/admin.py
+++ b/account/admin.py
@@ -1,6 +1,5 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
-
from account.forms import UserAdminChangeForm, UserAdminCreationForm
from account.models import User
diff --git a/account/authorization.py b/account/authorization.py
index 661ada1..4ab7bdc 100644
--- a/account/authorization.py
+++ b/account/authorization.py
@@ -1,5 +1,4 @@
from datetime import timedelta
-
from django.conf import settings
from django.contrib.auth import get_user_model
from jose import jwt, JWTError
@@ -9,6 +8,7 @@
TIME_DELTA = timedelta(days=120)
+
class GlobalAuth(HttpBearer):
def authenticate(self, request, token):
try:
@@ -24,4 +24,3 @@ def get_tokens_for_user(user):
return {
'access': str(token),
}
-
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/controllers.py b/commerce/controllers.py
index a8a551a..0bcd60a 100644
--- a/commerce/controllers.py
+++ b/commerce/controllers.py
@@ -9,8 +9,11 @@
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 commerce.models import Product, Category, City, Vendor, Item, Address,\
+ Order, OrderStatus
+from commerce.schemas import ProductOut, CitiesOut, CitySchema, VendorOut,\
+ ItemOut, ItemSchema, ItemCreate, CategoryOut, AddressSchema, AddressesOut,\
+ AddressesCreate, AddressesUpdate, OrderSchema, OrderCreate
from config.utils.schemas import MessageOut
products_controller = Router(tags=['products'])
@@ -20,9 +23,15 @@
User = get_user_model()
+
@vendor_controller.get('', response=List[VendorOut])
def list_vendors(request):
- return Vendor.objects.all()
+ vendor_set = Vendor.objects.all()
+
+ if vendor_set:
+ return vendor_set
+
+ return 400, {'detail': 'No categories found'}
@products_controller.get('', response={
@@ -30,32 +39,32 @@ def list_vendors(request):
404: MessageOut
})
def list_products(
- request, *,
- q: str = None,
- price_from: int = None,
- price_to: int = None,
- vendor=None,
+ request, *,
+ q: str = None,
+ price_from: int = None,
+ price_to: int = None,
+ vendor=None,
):
- products_qs = Product.objects.filter(is_active=True).select_related('merchant', 'vendor', 'category', 'label')
+ products_set = Product.objects.filter(is_active=True).select_related('merchant', 'vendor', 'category', 'label')
- if not products_qs:
+ if not products_set:
return 404, {'detail': 'No products found'}
if q:
- products_qs = products_qs.filter(
+ products_set = products_set.filter(
Q(name__icontains=q) | Q(description__icontains=q)
)
if price_from:
- products_qs = products_qs.filter(discounted_price__gte=price_from)
+ products_set = products_set.filter(discounted_price__gte=price_from)
if price_to:
- products_qs = products_qs.filter(discounted_price__lte=price_to)
+ products_set = products_set.filter(discounted_price__lte=price_to)
if vendor:
- products_qs = products_qs.filter(vendor_id=vendor)
+ products_set = products_set.filter(vendor_id=vendor)
- return products_qs
+ return products_set
"""
@@ -114,14 +123,17 @@ def list_products(
"""
-@address_controller.get('')
-def list_addresses(request):
- pass
+@products_controller.get('categories', response={
+ 200: List[CategoryOut],
+ 404: MessageOut
+})
+def list_categories(request):
+ category_set = Category.objects.all()
+ if category_set:
+ return category_set
-# @products_controller.get('categories', response=List[CategoryOut])
-# def list_categories(request):
-# return Category.objects.all()
+ return 404, {'detail': 'No categories found'}
@address_controller.get('cities', response={
@@ -129,10 +141,10 @@ def list_addresses(request):
404: MessageOut
})
def list_cities(request):
- cities_qs = City.objects.all()
+ city_set = City.objects.all()
- if cities_qs:
- return cities_qs
+ if city_set:
+ return city_set
return 404, {'detail': 'No cities found'}
@@ -175,12 +187,65 @@ def delete_city(request, id: UUID4):
return 204, {'detail': ''}
-@order_controller.get('cart', response={
+@address_controller.get('', auth=GlobalAuth(), response={
+ 200: List[AddressesOut],
+ 404: MessageOut
+})
+def list_addresses(request):
+ address_set = Address.objects.filter(user=request.auth['pk'])
+
+ if address_set:
+ return address_set
+
+ return 404, {'detail': 'No addresses found'}
+
+
+@address_controller.get('{id}', auth=GlobalAuth(), response={
+ 200: AddressesOut,
+ 404: MessageOut
+})
+def retrieve_address(request, id: UUID4):
+ return get_object_or_404(Address, id=id, user=request.auth['pk'])
+
+
+@address_controller.post('', auth=GlobalAuth(), response={
+ 201: AddressesOut,
+ 400: MessageOut
+})
+def create_address(request, address_in: AddressesCreate):
+ address = Address(**address_in.dict())
+ address.user = request.auth['pk']
+ address.save()
+ return 201, address
+
+
+@address_controller.put('{id}', auth=GlobalAuth(), response={
+ 200: AddressesOut,
+ 400: MessageOut
+})
+def update_address(request, id: UUID4, address_in: AddressesUpdate):
+ address = get_object_or_404(Address, id=id, user=request.auth['pk'])
+ for attr, value in address_in.dict().items():
+ setattr(address, attr, value)
+ address.save()
+ return 200, address
+
+
+@address_controller.delete('{id}', auth=GlobalAuth(), response={
+ 204: MessageOut
+})
+def delete_address(request, id: UUID4):
+ address = get_object_or_404(Address, id=id, user=request.auth['pk'])
+ address.delete()
+ return 204, {'detail': ''}
+
+
+@order_controller.get('cart', auth=GlobalAuth(), 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=request.auth['pk'], ordered=False)
if cart_items:
return cart_items
@@ -188,70 +253,123 @@ def view_cart(request):
return 404, {'detail': 'Your cart is empty, go shop like crazy!'}
-@order_controller.post('add-to-cart', response={
+@order_controller.post('add-to-cart', auth=GlobalAuth(), 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=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=request.auth['pk'])
return 200, {'detail': 'Added to cart successfully'}
-@order_controller.post('item/{id}/reduce-quantity', response={
+@order_controller.post('item/{id}/reduce-quantity', auth=GlobalAuth(), response={
200: MessageOut,
})
-def reduce_item_quantity(request, id: UUID4):
- item = get_object_or_404(Item, id=id, user=User.objects.first())
+def reduce_item_quantity(request, id: UUID4, qty: int = 1):
+ item = get_object_or_404(Item, id=id, user=request.auth['pk'])
if item.item_qty <= 1:
item.delete()
return 200, {'detail': 'Item deleted!'}
- item.item_qty -= 1
+ item.item_qty -= qty
item.save()
return 200, {'detail': 'Item quantity reduced successfully!'}
-@order_controller.delete('item/{id}', response={
+@order_controller.post('item/{id}/increase-quantity', auth=GlobalAuth(), response={
+ 200: MessageOut,
+})
+def increase_item_quantity(request, id: UUID4, qty: int = 1):
+ item = get_object_or_404(Item, id=id, user=request.auth['pk'])
+ item.item_qty += qty
+ item.save()
+ return 200, {'detail': 'Item quantity increased successfully!'}
+
+
+@order_controller.delete('item/{id}', auth=GlobalAuth(), 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=request.auth['pk'])
item.delete()
return 204, {'detail': 'Item deleted!'}
-def generate_ref_code():
- return ''.join(random.sample(string.ascii_letters + string.digits, 6))
+@order_controller.get('', auth=GlobalAuth(), response={
+ 200: List[OrderSchema],
+ 404: MessageOut
+})
+def list_orders(request, ordered: bool = False):
+ order_set = Order.objects.filter(user=request.auth['pk'])
+ if not ordered:
+ order_set = order_set.filter(ordered=ordered)
+ if not order_set:
+ return 404, {'detail': 'no orders found'}
+ return order_set
-@order_controller.post('create-order', auth=GlobalAuth(), response=MessageOut)
-def create_order(request):
- '''
- * add items and mark (ordered) field as True
- * add ref_number
- * add NEW status
- * calculate the total
- '''
+def gen_code(size=6):
+ chars = string.ascii_letters + string.digits
+ code = ''.join(random.choice(chars) for _ in range(size))
+ return code
- 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_controller.post('create-order', auth=GlobalAuth(), response={
+ 200: MessageOut
+})
+def create_order(request, item_in: OrderCreate):
+ user = User.objects.get(id=request.auth['pk'])
+ items = Item.objects.filter(id__in=item_in.items, user=request.auth['pk'])
+ current_order = Order.objects.filter(user=user, ordered=False)
+
+ if current_order.exists():
+ new_order = current_order.first()
+ for i in items:
+ i.ordered = True
+ i.save()
+ new_order.items.add(*items)
+ new_order.total = new_order.order_total
+ new_order.save()
+ return 200, {'detail': 'updated the order successfully.'}
+ else:
+ for i in items:
+ i.ordered = True
+ i.save()
+ status = OrderStatus.objects.get(title="NEW")
+ new_order = Order.objects.create(
+ user=user,
+ status=status,
+ address=item_in.address,
+ ordered=False,
+ ref_code=gen_code(),
+ note=item_in.note
+ )
+ new_order.items.add(*items)
+ new_order.total = new_order.order_total
+ new_order.save()
+ return 200, {'detail': 'created the order successfully.'}
- 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'}
+@order_controller.post('checkout', response={
+ 200: MessageOut,
+ 404: MessageOut
+})
+def checkout_order(request):
+ try:
+ order_set = Order.objects.get(ordered=False, user=request.auth['pk'])
+ except Order.DoesNotExist:
+ return 404, {'detail': 'No order exists'}
+
+ for item in order_set.items.all():
+ item.product.qty -= item.item_qty
+ item.product.save()
+ order_set.ordered = True
+ order_set.save()
+ return 200, {'detail': 'checkout successful'}
diff --git a/commerce/models.py b/commerce/models.py
index b0446b8..e128d92 100644
--- a/commerce/models.py
+++ b/commerce/models.py
@@ -1,11 +1,10 @@
import uuid
-
from PIL import Image
from django.contrib.auth import get_user_model
from django.db import models
-
from config.utils.models import Entity
+
User = get_user_model()
@@ -98,6 +97,10 @@ class OrderStatus(Entity):
])
is_default = models.BooleanField('is default')
+ class Meta:
+ verbose_name = 'order status'
+ verbose_name_plural = 'order statuses'
+
def __str__(self):
return self.title
@@ -114,7 +117,6 @@ class Category(Entity):
image = models.ImageField('image', upload_to='category/')
is_active = models.BooleanField('is active')
-
def __str__(self):
if self.parent:
return f'- {self.name}'
@@ -128,6 +130,7 @@ class Meta:
def children(self):
return self.children
+
class Merchant(Entity):
name = models.CharField('name', max_length=255)
@@ -206,5 +209,9 @@ class Address(Entity):
city = models.ForeignKey(City, related_name='addresses', on_delete=models.CASCADE)
phone = models.CharField('phone', max_length=255)
+ class Meta:
+ verbose_name = 'address'
+ verbose_name_plural = 'addresses'
+
def __str__(self):
return f'{self.user.first_name} - {self.address1} - {self.address2} - {self.phone}'
diff --git a/commerce/schemas.py b/commerce/schemas.py
index 5d68396..8526b77 100644
--- a/commerce/schemas.py
+++ b/commerce/schemas.py
@@ -7,15 +7,13 @@
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 +40,10 @@ class CategoryOut(UUIDSchema):
class ProductOut(ModelSchema):
- vendor: VendorOut
+ category: CategoryOut
label: LabelOut
merchant: MerchantOut
- category: CategoryOut
+ vendor: VendorOut
class Config:
model = Product
@@ -55,11 +53,10 @@ class Config:
'qty',
'price',
'discounted_price',
- 'vendor',
'category',
'label',
'merchant',
-
+ 'vendor',
]
@@ -75,11 +72,31 @@ class CitiesOut(CitySchema, UUIDSchema):
pass
+class AddressSchema(Schema):
+ # user:
+ work_address: bool = False
+ address1: str
+ address2: str = None
+ phone: str
+
+
+class AddressesCreate(AddressSchema):
+ city_id: UUID4
+
+
+class AddressesUpdate(AddressSchema):
+ city_id: UUID4
+
+
+class AddressesOut(AddressSchema, UUIDSchema):
+ city: CitiesOut
+
+
class ItemSchema(Schema):
# user:
- product: ProductOut
item_qty: int
ordered: bool
+ product: ProductOut
class ItemCreate(Schema):
@@ -87,7 +104,30 @@ class ItemCreate(Schema):
item_qty: int
-class ItemOut(UUIDSchema, ItemSchema):
+class ItemOut(ItemSchema, UUIDSchema):
pass
+class OrderStatusOut(Schema):
+ title: str
+
+
+class UserOut(Schema):
+ username: str
+
+
+class OrderSchema(Schema):
+ items: List[ItemSchema]
+ status: OrderStatusOut
+ address: AddressesOut
+ order_total: float
+ ordered: bool
+ user: UserOut
+ ref_code: str
+ note: str
+
+
+class OrderCreate(Schema):
+ items: List[UUID4]
+ address: UUID4
+ note: str
diff --git a/requirements.txt b/requirements.txt
index 5d025cd..0d0635f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,3 +6,4 @@ pydantic==1.8.2
pytz==2021.3
sqlparse==0.4.2
typing-extensions==3.10.0.2
+python-jose==3.3.0