From 4ce8b28a9c8084718c4bd54f94672672d132a309 Mon Sep 17 00:00:00 2001 From: Anas_Ezio Date: Mon, 1 Nov 2021 00:51:07 +0300 Subject: [PATCH] Happy coding --- commerce/controllers.py | 72 ++++++++++++++++++++++++++++++++++++----- commerce/models.py | 21 +++++++----- commerce/schemas.py | 15 +++++++-- config/urls.py | 3 +- 4 files changed, 91 insertions(+), 20 deletions(-) diff --git a/commerce/controllers.py b/commerce/controllers.py index 0d8791b..399b751 100644 --- a/commerce/controllers.py +++ b/commerce/controllers.py @@ -1,18 +1,22 @@ from typing import List - +from uuid import uuid4 +from typing import List +import string +import random from django.contrib.auth.models import User from django.db.models import Q from django.shortcuts import get_object_or_404 +from django.utils import tree from ninja import Router from pydantic import UUID4 - -from commerce.models import Product, Category, City, Vendor, Item -from commerce.schemas import MessageOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate +from commerce.models import Address, Order, OrderStatus, Product, Category, City, Vendor, Item +from commerce.schemas import CheckoutSchema, MessageOut, ProductOut, CitiesOut, CitySchema, VendorOut, ItemOut, ItemSchema, ItemCreate, AddressOut 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]) @@ -31,7 +35,8 @@ def list_products( price_to: int = None, vendor=None, ): - products_qs = Product.objects.filter(is_active=True).select_related('merchant', 'vendor', 'category', 'label') + products_qs = Product.objects.filter(is_active=True).select_related( + 'merchant', 'vendor', 'category', 'label') if not products_qs: return 404, {'detail': 'No products found'} @@ -109,9 +114,9 @@ def list_products( """ -@address_controller.get('') +@address_controller.get('', response=List[AddressOut]) def list_addresses(request): - pass + return Address.objects.all() # @products_controller.get('categories', response=List[CategoryOut]) @@ -189,7 +194,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.objects.get( + product_id=item_in.product_id, user=User.objects.first()) item.item_qty += 1 item.save() except Item.DoesNotExist: @@ -220,3 +226,53 @@ def delete_item(request, id: UUID4): item.delete() return 204, {'detail': 'Item deleted!'} + + @order_controller.post('item/{id}/increase_quantity', response={ + 200: MessageOut + }) + @order_controller.post() + def increase_item_quantity(request, id: uuid4): + item = get_object_or_404(Item, id=id, User=User.objects.first()) + if item.item_qty > 1: + item.update() + return 200, {'detail': 'Item added'} + item.item_qty += 1 + item.save() + return 200, {'detail', 'Item auantity increase successfully'} + + +def generate_ref_code(): + return ''.join(random.sample(string.ascii_letters+string.digits, 6)) + + +@order_controller.post('create_order') +def create_order(request): + order_qs = Order( + 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()) + user_items.update(ordered=True) + order_qs.items.append(*user_items) + order_qs.total = order_qs.order_total + order_qs.save() + return {'detail': 'thanks the order created successfuly'} + + +@checkout_controller.post('checkout_note', response={ + 200: List[CheckoutSchema], + 404: MessageOut +}) +def List_checkout( + request, *, + q: str = None, +): + checkout_qs = Item.objects.filter(user=User.objects.first(), ordered=False) + + if checkout_qs: + return checkout_qs + + return 404, {'detail': 'checkout please '} diff --git a/commerce/models.py b/commerce/models.py index 2d9bfa6..7be9b37 100644 --- a/commerce/models.py +++ b/commerce/models.py @@ -1,5 +1,4 @@ import uuid - from PIL import Image from django.contrib.auth import get_user_model from django.db import models @@ -26,7 +25,8 @@ class Product(Entity): qty = models.DecimalField('qty', max_digits=10, decimal_places=2) cost = models.DecimalField('cost', max_digits=10, decimal_places=2) price = models.DecimalField('price', max_digits=10, decimal_places=2) - discounted_price = models.DecimalField('discounted price', max_digits=10, decimal_places=2) + discounted_price = models.DecimalField( + 'discounted price', max_digits=10, decimal_places=2) vendor = models.ForeignKey('commerce.Vendor', verbose_name='vendor', related_name='products', on_delete=models.SET_NULL, null=True, blank=True) @@ -52,13 +52,15 @@ class Order(Entity): on_delete=models.CASCADE) address = models.ForeignKey('commerce.Address', verbose_name='address', null=True, blank=True, on_delete=models.CASCADE) - total = models.DecimalField('total', blank=True, null=True, max_digits=1000, decimal_places=0) + total = models.DecimalField( + 'total', blank=True, null=True, max_digits=1000, decimal_places=0) status = models.ForeignKey('commerce.OrderStatus', verbose_name='status', related_name='orders', on_delete=models.CASCADE) note = models.CharField('note', null=True, blank=True, max_length=255) ref_code = models.CharField('ref code', max_length=255) ordered = models.BooleanField('ordered') - items = models.ManyToManyField('commerce.Item', verbose_name='items', related_name='order') + items = models.ManyToManyField( + 'commerce.Item', verbose_name='items', related_name='order') def __str__(self): return f'{self.user.first_name} + {self.total}' @@ -75,7 +77,8 @@ class Item(Entity): Product can live alone in the system, while Item can only live within an order """ - user = models.ForeignKey(User, verbose_name='user', related_name='items', on_delete=models.CASCADE) + user = models.ForeignKey(User, verbose_name='user', + related_name='items', on_delete=models.CASCADE) product = models.ForeignKey('commerce.Product', verbose_name='product', on_delete=models.CASCADE) item_qty = models.IntegerField('item_qty') @@ -121,7 +124,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}' @@ -135,6 +137,7 @@ class Meta: def children(self): return self.children + class Merchant(Entity): name = models.CharField('name', max_length=255) @@ -209,8 +212,10 @@ class Address(Entity): on_delete=models.CASCADE) work_address = models.BooleanField('work address', null=True, blank=True) address1 = models.CharField('address1', max_length=255) - address2 = models.CharField('address2', null=True, blank=True, max_length=255) - city = models.ForeignKey(City, related_name='addresses', on_delete=models.CASCADE) + address2 = models.CharField( + 'address2', null=True, blank=True, max_length=255) + city = models.ForeignKey( + City, related_name='addresses', on_delete=models.CASCADE) phone = models.CharField('phone', max_length=255) def __str__(self): diff --git a/commerce/schemas.py b/commerce/schemas.py index 5b7d0d4..0150d81 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 pydantic import UUID4 - -from commerce.models import Product, Merchant +from pydantic.schema import model_schema +from commerce.models import City, Product, Merchant, Address class MessageOut(Schema): @@ -42,6 +41,13 @@ class CategoryOut(UUIDSchema): CategoryOut.update_forward_refs() +class AddressOut(ModelSchema): + address1: str + address2: str + City: str + phone: str + + class ProductOut(ModelSchema): vendor: VendorOut label: LabelOut @@ -67,6 +73,9 @@ class Config: # class ProductManualSchemaOut(Schema): # pass +class CheckoutSchema(Schema): + note: str + class CitySchema(Schema): name: str diff --git a/config/urls.py b/config/urls.py index fea5e70..6f740e4 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('orders',checkout_controller) urlpatterns = [ path('admin/', admin.site.urls),