diff --git a/commerce/controllers.py b/commerce/controllers.py index a8a551a..e5f967a 100644 --- a/commerce/controllers.py +++ b/commerce/controllers.py @@ -9,14 +9,15 @@ 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 Address, Product, Category, City, Vendor, Item, Order, OrderStatus +from commerce.schemas import AddressIn, AddressesOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate, CheckOut from config.utils.schemas import MessageOut 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']) User = get_user_model() @@ -175,12 +176,12 @@ def delete_city(request, id: UUID4): return 204, {'detail': ''} -@order_controller.get('cart', response={ +@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,26 +189,31 @@ 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_qty += 1 - item.save() - except Item.DoesNotExist: - Item.objects.create(**item_in.dict(), user=User.objects.first()) + user_items = Item.objects.filter(user=request.auth['pk']).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=request.auth['pk']) + item.item_qty += 1 + item.save() + except Item.DoesNotExist: + Item.objects.create(**item_in.dict(), user=request.auth['pk']) + + return 200, {'detail': 'Added to cart successfully'} + return 400, {'detail': 'You are allready have items'} - 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()) + item = get_object_or_404(Item, id=id, user=request.auth['pk']) if item.item_qty <= 1: item.delete() return 200, {'detail': 'Item deleted!'} @@ -217,11 +223,11 @@ def reduce_item_quantity(request, id: UUID4): return 200, {'detail': 'Item quantity reduced successfully!'} -@order_controller.delete('item/{id}', response={ +@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!'} @@ -239,19 +245,116 @@ def create_order(request): * add NEW status * calculate the total ''' - - order_qs = Order.objects.create( - user=User.objects.first(), + #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=request.auth['pk'], 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=request.auth['pk']).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', auth=GlobalAuth(), response={ + 200: MessageOut, +}) +def increase_item_quantity(request, id: UUID4): + item = get_object_or_404(Item, id=id, user=request.auth['pk']) + 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 404, {'detail': 'No addresses found'} + - return {'detail': 'order created successfully'} +@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', auth=GlobalAuth(), response={ + 400: MessageOut, + 200: CheckOut +}) +def checkout_create(request, check_out: CheckOut): + checkout_obj = get_object_or_404(Order, user=request.auth['pk'], 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'} \ No newline at end of file diff --git a/commerce/schemas.py b/commerce/schemas.py index 5d68396..b4a6a87 100644 --- a/commerce/schemas.py +++ b/commerce/schemas.py @@ -1,9 +1,6 @@ -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 @@ -90,4 +87,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]