Skip to content
Open
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
174 changes: 150 additions & 24 deletions commerce/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from ninja import Router
from pydantic import UUID4

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 Product, Category, City, Vendor, Item, Order, OrderStatus, Order, Address
from commerce.schemas import MessageOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate, AddressOut, CheckoutSchema, CheckoutSchemaOut, AddressUpdate, AddressCreate, OrderOut

products_controller = Router(tags=['products'])
address_controller = Router(tags=['addresses'])
Expand Down Expand Up @@ -111,9 +111,17 @@ def list_products(
"""


@address_controller.get('')
@address_controller.get('', response={
200: List[AddressOut],
404: MessageOut
})
def list_addresses(request):
pass
addresses_qs = Address.objects.all()

if addresses_qs:
return addresses_qs

return 404, {'detail': 'No addresses found'}


# @products_controller.get('categories', response=List[CategoryOut])
Expand Down Expand Up @@ -191,8 +199,8 @@ def view_cart(request):
})
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 = Item.objects.get(product_id=item_in.product_id, user=User.objects.first(), ordered=False)
item.item_qty += item_in.item_qty
item.save()
except Item.DoesNotExist:
Item.objects.create(**item_in.dict(), user=User.objects.first())
Expand Down Expand Up @@ -228,27 +236,145 @@ def generate_ref_code():
return ''.join(random.sample(string.ascii_letters + string.digits, 6))


@order_controller.post('create-order', response=MessageOut)
# @order_controller.post('create-order', response=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'}

# endpoint for increasing an item quantity within an order
@order_controller.post('item/{id}/increase-quantity', response={
200: MessageOut,
404: 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!'}

# create-order endpoint
@order_controller.post('create-order', response={
200: MessageOut,
404: 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(),
user_items = Item.objects.filter(user=User.objects.first(), ordered=False)
active_order = Order.objects.get(user=User.objects.first(), ordered=False, status__is_default = True)

if user_items:
if active_order:
for item in user_items:
item_product = item.product_id
if item_product in active_order.items.values('product_id'):
order_item = active_order.items.filter(product_id=item_product)
order_item.qty += item.qty
order_item.save()
else:
active_order.items.add(item)
else:
active_order = Order.objects.create(user=User.objects.first(),
status=OrderStatus.objects.get(is_default=True),
ref_code=generate_ref_code(),
ordered=False,
)
ordered=False
)
active_order.items.add(*user_items)

active_order.items.update(ordered=True)
active_order.total = active_order.order_total
active_order.save()
return 200, {'detail': 'An order was issued successfully'}

return 404, {'detail': 'No items in cart to be ordered'}

######## addresses CRUD endpoints
#get an address
@address_controller.get('addresses/{id}', response={
200: AddressOut,
404: MessageOut
})
def retrieve_address(request, id: UUID4):
return get_object_or_404(Address, id=id)

#create an addresss
@address_controller.post('addresses', response={
201: AddressOut,
400: MessageOut
})
def create_address(request, address_in: AddressCreate):
address = Address(**address_in.dict(), user=User.objects.first())
address.save()
return 201, address

#update an address
@address_controller.put('addresses/{id}', response={
200: AddressOut,
400: MessageOut
})
def update_address(request, id: UUID4, address_in: AddressUpdate):
address = get_object_or_404(Address, id=id)
for attr, val in address_in.dict().items():
setattr(address, attr, val)

address.save()
return 200, address

user_items = Item.objects.filter(user=User.objects.first()).filter(ordered=False)
#delete an addresss
@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': ''}

#implement checkout endpoint
@order_controller.post('checkout', response={
201: list[CheckoutSchemaOut],
404: MessageOut
})
def checkout(request, checkout_in: CheckoutSchema):
try:
order = Order.objects.get(user=User.objects.first(), status__is_default=True)
for attr, val in checkout_in.dict().items():
setattr(order, attr, val)
order.ordered= True
order.status= OrderStatus.objects.get(title="COMPLETED")
order.save()

except Order.DoesNotExist:
return 404, {"detail" : "No order to checkout"}

return 201, order

@order_controller.get('', response={
200: list[OrderOut],
404: MessageOut
})
def view_orders(request):
orders = Order.objects.filter(user=User.objects.first())

order_qs.items.add(*user_items)
order_qs.total = order_qs.order_total
user_items.update(ordered=True)
order_qs.save()
if orders:
return orders

return {'detail': 'order created successfully'}
return 404, {'detail': 'No orders to show!'}
4 changes: 4 additions & 0 deletions commerce/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def order_total(self):
return sum(
i.product.discounted_price * i.item_qty for i in self.items.all()
)

@property
def children(self):
return self.children


class Item(Entity):
Expand Down
42 changes: 40 additions & 2 deletions commerce/schemas.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import List
from typing import List, Optional

from ninja import ModelSchema, Schema
from ninja.orm import create_schema
from pydantic import UUID4

from commerce.models import Product, Merchant
from commerce.models import Product, Merchant, Address, Order


class MessageOut(Schema):
Expand Down Expand Up @@ -92,3 +92,41 @@ class ItemOut(UUIDSchema, ItemSchema):
pass


class OrderOut(ModelSchema):
class Config:
model = Order
model_fields = ['total', 'ordered']

class OrderStatusOut(UUIDSchema):
status: str

class AddressUpdate(Schema):
# user_id: UUID4
work_address: Optional[bool]
address2: Optional[str]
address1: Optional[str]
city_id: Optional[UUID4]
phone: Optional[str]

class AddressCreate(Schema):
# user_id: UUID4
address1: str
city_id: UUID4
phone: str


class AddressOut(ModelSchema):
city: CitySchema
class Config:
model = Address
model_fields = ['id','phone', 'address1', 'address2', 'work_address']

class CheckoutSchema(Schema):
note: Optional[str]
address_id: Optional[UUID4]

class CheckoutSchemaOut(CheckoutSchema):
note: str
address: AddressOut
ordered: bool
total: int