diff --git a/apps/backend/Orders/migrations/0012_auto_20220212_0445.py b/apps/backend/Orders/migrations/0012_auto_20220212_0445.py new file mode 100644 index 0000000..3f322e9 --- /dev/null +++ b/apps/backend/Orders/migrations/0012_auto_20220212_0445.py @@ -0,0 +1,43 @@ +# Generated by Django 3.1.13 on 2022-02-12 04:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('Users', '0008_auto_20220206_1710'), + ('Orders', '0011_order_fulfillment_status'), + ] + + operations = [ + migrations.RemoveField( + model_name='orderitem', + name='Address', + ), + migrations.RemoveField( + model_name='orderitem', + name='fullfillment_status', + ), + migrations.AddField( + model_name='order', + name='Address', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='Users.address'), + ), + migrations.AddField( + model_name='order', + name='discount_percent', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='order', + name='tax_percent', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='orderitem', + name='fulfillment_status', + field=models.CharField(choices=[('Unfulfilled', 'Unfulfilled'), ('PartiallyFulfilled', 'PartiallyFulfilled'), ('Fulfilled', 'Fulfilled')], default='Unfulfilled', max_length=50), + ), + ] diff --git a/apps/backend/Orders/migrations/0013_auto_20220212_1244.py b/apps/backend/Orders/migrations/0013_auto_20220212_1244.py new file mode 100644 index 0000000..8f290a3 --- /dev/null +++ b/apps/backend/Orders/migrations/0013_auto_20220212_1244.py @@ -0,0 +1,38 @@ +# Generated by Django 3.1.13 on 2022-02-12 12:44 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('Orders', '0012_auto_20220212_0445'), + ] + + operations = [ + migrations.RenameField( + model_name='order', + old_name='Customer', + new_name='customer', + ), + migrations.RenameField( + model_name='order', + old_name='extra_charges', + new_name='shipping_charges', + ), + migrations.RenameField( + model_name='orderitem', + old_name='Amount', + new_name='amount', + ), + migrations.RenameField( + model_name='orderitem', + old_name='Customer', + new_name='customer', + ), + migrations.RenameField( + model_name='orderitem', + old_name='Quantity', + new_name='quantity', + ), + ] diff --git a/apps/backend/Orders/models.py b/apps/backend/Orders/models.py index faa4805..dfef25a 100644 --- a/apps/backend/Orders/models.py +++ b/apps/backend/Orders/models.py @@ -1,11 +1,14 @@ +import operator +from functools import reduce from django.db import models from Users.models import Customer, Address +from cart.models import document_exists from shop.models import Product # Create your models here. class Order(models.Model): - Customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING) + customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING) paid = models.BooleanField(default=False) payment_methods = (("0", "stripe_checkout"), ("1", "PaymentIntent")) @@ -36,41 +39,81 @@ class Order(models.Model): choices=Fullfilment_Statuses, default="Unfulfilled", max_length=50 ) + address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, null=True) + tax_percent = models.IntegerField(default=0) + discount_percent = models.IntegerField(default=0) + shipping_charges = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) - extra_charges = models.IntegerField(default=0) def __str__(self): - return f"{self.Customer} {self.id}" + return f"{self.customer} {self.id}" + @property def total_amount(self): items = OrderItem.objects.filter(order=self) - total_amount = self.extra_charges - for item in items: - total_amount += item.total_amount() - return total_amount + subtotal = sum((x.total_amount for x in items)) + subtotal = subtotal + self.shipping_charges + subtotal = subtotal - (subtotal * self.discount_percent / 100) + return subtotal + (subtotal * self.tax_percent / 100) + + @property + def total_items(self): + + items = OrderItem.objects.filter(order=self) + return len(items) + + @property + def total_quantity(self): + + items = OrderItem.objects.filter(order=self) + return reduce(sum, map(lambda x: x.quantity, items)) + + @property + def total_weight(self): + items = OrderItem.objects.filter(order=self) + return reduce(sum, map(lambda x: x.product.weight * x.quantity, items)) + + @property + def total_weight_in_grams(self): + return self.total_weight() * 1000 + +# TODO : lowercase the quantity , weight , amount , customer in client class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE) product_id = models.CharField(max_length=100, null=False) variation_id = models.CharField(null=False, max_length=50) - Amount = models.IntegerField(null=False) # single item price - Customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING) - Address = models.ForeignKey(Address, on_delete=models.DO_NOTHING) - Quantity = models.IntegerField(null=False) + amount = models.IntegerField(null=False) # single item price + customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING) + + quantity = models.IntegerField(null=False) Order_date = models.DateTimeField(auto_now_add=True, blank=True) details = models.TextField(max_length=500, null=True) paid = models.BooleanField(default=False) - fullfillment_status = models.CharField(max_length=200, default="Unpaid") + Fullfilment_Statuses = ( + ("Unfulfilled", "Unfulfilled"), + ("PartiallyFulfilled", "PartiallyFulfilled"), + ("Fulfilled", "Fulfilled"), + ) + fulfillment_status = models.CharField( + choices=Fullfilment_Statuses, default="Unfulfilled", max_length=50 + ) + + @property def total_amount(self): - return self.Amount * self.Quantity + return self.amount * self.quantity @property def product(self): - return Product.objects.get(id=self.product_id) + + if document_exists(lambda: Product.objects.get(id=self.product_id)): + return Product.objects.get(id=self.product_id) + else: + return Product(name="does not exist") def __str__(self): return str(self.id) diff --git a/apps/backend/Orders/schema.py b/apps/backend/Orders/schema.py index d23c5aa..b2d8356 100644 --- a/apps/backend/Orders/schema.py +++ b/apps/backend/Orders/schema.py @@ -1,8 +1,10 @@ +from ast import Str +import base64 from shop.types import ProductType, VariationType from django.core.paginator import Paginator import graphene -from graphene import relay - +from graphene import Int, relay +import json from graphene_django import DjangoObjectType, DjangoConnectionField from graphene_django.filter import DjangoFilterConnectionField @@ -10,37 +12,35 @@ from Users.models import User, Customer, Address from cart.cart import Cart from cart.models import PersistentCart -from graphql_jwt.decorators import login_required +from graphql_jwt.decorators import login_required, superuser_required from django_filters import FilterSet, OrderingFilter +def object_id_from_global_id(global_id: Str) -> Int: + global_id_decoded = base64.decodebytes(bytes(global_id, "utf-8")).decode("utf-8") + return int(global_id_decoded.split(":")[1]) + + class OrderFilter(FilterSet): class Meta: model = Order fields = { "id": ["exact"], - "Customer": ["exact"], + "customer": ["exact"], "paid": ["exact"], "payment_method": ["exact"], "payment_status": ["exact"], "fulfillment_status": ["exact"], - "created_at": ["exact"], + "created_at": ["exact", "gt", "gte", "lt", "lte", "range", "date"], "updated_at": ["exact"], - "extra_charges": ["exact"], + # "extra_charges": ["exact"], } order_by = OrderingFilter(fields=(("updated_at", "created_at"),)) -class PaginationType(graphene.ObjectType): - - page_no = graphene.Int() - total_pages = graphene.Int() - total_count = graphene.Int() - - class CountableConnectionBase(relay.Connection): class Meta: abstract = True @@ -61,7 +61,7 @@ class Meta: def resolve_totalAmount(self, info): - return self.total_amount() + return self.total_amount class OrderItemType(DjangoObjectType): @@ -73,14 +73,16 @@ class Meta: totalAmount = graphene.Int() def resolve_totalAmount(self, info): - return self.total_amount() + return self.total_amount def resolve_product(self, info): return self.product def resolve_variation(self, info): + for v in self.product.variations: + if str(v._id) == self.variation_id: return v @@ -98,6 +100,8 @@ class Query(graphene.ObjectType): @login_required def resolve_order(self, info, id=None, get_current=None): user = info.context.user + if id is not None: + id = object_id_from_global_id(id) if get_current: session = info.context.session @@ -162,13 +166,14 @@ def mutate(root, info, input): customer = Customer.objects.get(user=user) - order = Order(Customer=customer) - order.save() # address=Address.objects.get(pk=input.address_id) if input.is_primary: address = customer.default_address else: address = customer.Addresses.get(pk=int(input.address_id)) + order = Order(customer=customer, address=address) + order.save() + order_items = [] for item in cart.products(): @@ -182,10 +187,9 @@ def mutate(root, info, input): order_item = OrderItem( order=order, product_id=str(product_id), - Amount=price, - Address=address, - Customer=customer, - Quantity=item.quantity, + amount=price, + customer=customer, + quantity=item.quantity, variation_id=str(variation_id), ) @@ -197,5 +201,22 @@ def mutate(root, info, input): return CreateOrderMutation(order=order, order_items=order_items) +class UpdateOrderMutation(graphene.Mutation): + + order = graphene.Field(OrderNode) + + class Arguments: + order_id = graphene.String() + fulfillment_status = graphene.String() + + def mutate(self, info, order_id, fulfillment_status, **kwargs): + id = object_id_from_global_id(order_id) + order = Order.objects.get(pk=id) + order.fulfillment_status = fulfillment_status + order.save() + return UpdateOrderMutation(order=order) + + class Mutation(graphene.ObjectType): create_order = CreateOrderMutation.Field() + update_order = UpdateOrderMutation.Field() diff --git a/apps/backend/Users/schema.py b/apps/backend/Users/schema.py index 372c077..c7d31ba 100644 --- a/apps/backend/Users/schema.py +++ b/apps/backend/Users/schema.py @@ -1,24 +1,27 @@ -import os - # third party packages import graphene -import requests -from graphene_django.types import DjangoObjectType, ObjectType -from graphene_mongo import MongoengineObjectType +from graphene_django.types import DjangoObjectType from graphql_auth.schema import UserQuery, MeQuery from graphql_auth import mutations from graphql_auth.models import UserStatus -from graphql_jwt.decorators import login_required +from graphql_jwt.decorators import login_required, superuser_required +from graphene_django.filter import DjangoFilterConnectionField +from django_filters import FilterSet +from utils import CountableConnectionBase +from graphene import relay + # app packages from .models import User, Customer, Address -from cart.decorators import migrate_cart_to_db,migrate_cart_to_session +from cart.decorators import migrate_cart_to_db, migrate_cart_to_session + class UserType(DjangoObjectType): class Meta: model = User - + verified = graphene.Boolean() - def resolve_verified(self,*args,**kwargs): + + def resolve_verified(self, *args, **kwargs): return self.status.verified @@ -31,6 +34,7 @@ class AddressType(DjangoObjectType): class Meta: model = Address + class MeQuery(MeQuery): class Meta: abstract = True @@ -42,46 +46,69 @@ def resolve_me(self, info): return info.context.user +class CustomerFilter(FilterSet): + class Meta: + model = Customer + fields = { + "user": ["exact"], + "user__first_name": ["exact"], + "user__last_name": ["exact"], + "user__email": ["exact"], + "phone_number": ["exact"], + } + + +class CustomerNode(DjangoObjectType): + class Meta: + model = Customer + interfaces = (relay.Node,) + connection_class = CountableConnectionBase + + total_orders = graphene.Int() + + def resolve_total_orders(self, info): + return self.orders.count() + + class Query(UserQuery, MeQuery, graphene.ObjectType): # user=graphene.Field(UserType) customer = graphene.Field(CustomerType) # users=graphene.List(UserType) - customers = graphene.List(CustomerType) + # customers = graphene.List(CustomerType) + + customers = DjangoFilterConnectionField( + CustomerNode, filterset_class=CustomerFilter + ) default_address = graphene.Field(AddressType) addresses = graphene.List(AddressType) - + + @superuser_required + def resolve_customers(self, info, **kwargs): + + return CustomerFilter(kwargs).qs + @login_required def resolve_customer(self, info, **kwargs): user = info.context.user - #print(user) + # print(user) if user.is_customer: customer = Customer.objects.get(user=user) - #print("customer", customer) + # print("customer", customer) return customer - raise Exception('You are not registerd as customer') + raise Exception("You are not registerd as customer") - def resolve_customers(self, info, **kwargs): - user = info.context.user - #print(user) - if user.is_superuser: - customers = Customer.objects.all() - #print("customer", customers) - return customers - raise Exception('You are not admin') - @login_required def resolve_default_address(self, info, **kwargs): user = info.context.user # if user.is_customer: - customer = Customer.objects.get( - user=user) - #print(customer) + customer = Customer.objects.get(user=user) + # print(customer) return customer.default_address @login_required def resolve_addresses(self, info, **kwargs): user = info.context.user - #print(user) + # print(user) customer = Customer.objects.get(user=user) return customer.Addresses.all() @@ -105,24 +132,24 @@ class AddAddressMutation(graphene.Mutation): class Arguments: address = AddressInput() + @login_required def mutate(self, info, address): user = info.context.user - is_primary =address.get("is_primary") + is_primary = address.get("is_primary") del address["is_primary"] - #print("address",address) + # print("address",address) # #print(user) customer = Customer.objects.get(user=user) address = Address(**address) address.save() - #print(address) - - + # print(address) + if is_primary: customer.default_address = address else: customer.Addresses.add(address) - + customer.save() return AddAddressMutation(address=address) @@ -132,6 +159,7 @@ class ChangeDefaultAddressMutation(graphene.Mutation): class Arguments: address_id = graphene.String() + @login_required def mutate(self, info, address_id): user = info.context.user @@ -143,7 +171,7 @@ def mutate(self, info, address_id): # p.update() # # add is_primary to new address address = customer.Addresses.get(id=address_id) - customer.default_address= address + customer.default_address = address # address.is_primary = True address.update() customer.update() @@ -156,6 +184,7 @@ class UpdateAddressMutation(graphene.Mutation): class Arguments: address_id = graphene.String() update_values = AddressInput() + @login_required def mutate(self, info, address_id, update_values): user = info.context.user @@ -164,31 +193,34 @@ def mutate(self, info, address_id, update_values): address = customer.Addresses.get(id=address_id) address.update_fields(update_values) if update_values.is_primary: - #print("setting as primary") + # print("setting as primary") customer.default_address = address customer.Addresses.remove(int(address_id)) - if update_values.is_primary== False and customer.default_address==address: - customer.default_address.delete() + if ( + update_values.is_primary == False + and customer.default_address == address + ): + customer.default_address.delete() address.save() customer.save() return UpdateAddressMutation(address=address) + class DeleteAddressMutation(graphene.Mutation): success = graphene.Boolean() - class Arguments : + class Arguments: address_id = graphene.String() @login_required - def mutate(self,info,address_id): + def mutate(self, info, address_id): user = info.context.user if user.is_authenticated: customer = Customer.objects.get(user=user) customer.Addresses.remove(int(address_id)) - if customer.default_address.id==int(address_id): + if customer.default_address.id == int(address_id): customer.default_address.delete() - # address.delete() return DeleteAddressMutation(success=True) @@ -196,18 +228,19 @@ def mutate(self,info,address_id): class TokenAuth(mutations.ObtainJSONWebToken): @classmethod @migrate_cart_to_db - def resolve_mutation(cls,root,info,**kwargs): - response = super().resolve_mutation(root,info,**kwargs) + def resolve_mutation(cls, root, info, **kwargs): + response = super().resolve_mutation(root, info, **kwargs) return response -class RevokeToken(mutations.RevokeToken): +class RevokeToken(mutations.RevokeToken): @classmethod @migrate_cart_to_session - def resolve_mutation(cls,root,info,**kwargs): - response = super().resolve_mutation(root,info,**kwargs) + def resolve_mutation(cls, root, info, **kwargs): + response = super().resolve_mutation(root, info, **kwargs) return response + class AuthMutation(graphene.ObjectType): register = mutations.Register.Field() verify_account = mutations.VerifyAccount.Field() @@ -236,4 +269,4 @@ class Mutation(AuthMutation, graphene.ObjectType): add_address = AddAddressMutation.Field() change_default_address = ChangeDefaultAddressMutation.Field() update_address = UpdateAddressMutation.Field() - delete_address=DeleteAddressMutation.Field() + delete_address = DeleteAddressMutation.Field() diff --git a/apps/backend/cart/models.py b/apps/backend/cart/models.py index df9e813..ea10647 100644 --- a/apps/backend/cart/models.py +++ b/apps/backend/cart/models.py @@ -1,46 +1,65 @@ -from xml.dom.minidom import DocumentFragment from django.db import models -from itsdangerous import exc + from mongoengine import * -from numpy import product -from shop.models import Product,Variation + +from shop.models import Product, Variation from .cart import AbstractCart + # Create your models here. + class CartItem(EmbeddedDocument): product = ReferenceField(Product) - variation= EmbeddedDocumentField(Variation) - quantity= IntField() + variation = EmbeddedDocumentField(Variation) + quantity = IntField() price = IntField() # Ptotal_price = IntField() + class FinalMeta(type(Document), type(AbstractCart)): pass -class PersistentCart(AbstractCart,Document,metaclass=FinalMeta): - user_id = IntField(required=True,null=False) - created_at= DateTimeField() + +class PersistentCart(AbstractCart, Document, metaclass=FinalMeta): + user_id = IntField(required=True, null=False) + created_at = DateTimeField() updated_at = DateTimeField() - items=ListField(EmbeddedDocumentField(CartItem)) - + items = ListField(EmbeddedDocumentField(CartItem)) + + def remove_deleted_products(self): + print("deleting") + @classmethod def get_or_create(cls, user_id): - try : + try: + print("fetch cart") cart = cls.objects.get(user_id=user_id) - except DoesNotExist : - cart = cls.objects.create(user_id=user_id) + + print("cart", cart) + except DoesNotExist: + cart = cls.objects.create(user_id=user_id) return cart def products(self): - return self.items - def add(self, product_id,variation_id,quantity=1, override_quantity=False): - #checks if item is in cart already - + valid_items = list( + filter(lambda item: document_exists(lambda: item.product), self.items) + ) + print("valid", valid_items) + self.items = valid_items + self.save() + return valid_items + + def add(self, product_id, variation_id, quantity=1, override_quantity=False): + # checks if item is in cart already + if quantity <= 0: - raise ValueError('Cannot add zero or negative quantities!') + raise ValueError("Cannot add zero or negative quantities!") for item in self.items: - if str(item.product.id) == product_id and str(item.variation._id) == variation_id: + if ( + str(item.product.id) == product_id + and str(item.variation._id) == variation_id + ): # item.price = item.variation.price if override_quantity: item.quantity = quantity @@ -48,43 +67,68 @@ def add(self, product_id,variation_id,quantity=1, override_quantity=False): item.quantity += 1 self.save() return - + # add new item if not in cart already - product= Product.objects.get(id=product_id) - variation=product.get_variation(variation_id) - item = CartItem(product=product,variation=variation,quantity=quantity,price=variation.price) + product = Product.objects.get(id=product_id) + variation = product.get_variation(variation_id) + item = CartItem( + product=product, + variation=variation, + quantity=quantity, + price=variation.price, + ) self.items.append(item) self.save() - def remove(self, product_id,variation_id): + def remove(self, product_id, variation_id): product = Product.objects.get(id=product_id) variation = product.get_variation(variation_id) - self.update(pull__items= CartItem(product=product,variation=variation)) + self.update(pull__items=CartItem(product=product, variation=variation)) def clear_cart(self): self.items = [] self.save() def get_total_price(self): - total_price=0 - for item in self.items : - total_price += (item.price * item.quantity) + total_price = 0 + for item in self.items: + total_price += item.price * item.quantity return total_price def total_items(self): - + return sum(item.quantity for item in self.items) - def add_from_session(self, session_cart): cart = session_cart.data() - for key,value in cart.items(): + for key, value in cart.items(): # print(key,value) - product_id,variation_id=key.split(',') - self.add(product_id,variation_id,quantity=value["quantity"],override_quantity=True) + product_id, variation_id = key.split(",") + self.add( + product_id, + variation_id, + quantity=value["quantity"], + override_quantity=True, + ) self.save() - - + +# def document_exists(func): +# def wrapper(*args, **kwargs): +# try: +# func(*args, **kwargs) +# return True +# except DoesNotExist as e: +# return False + +# return wrapper +def document_exists(callback, onerror=None): + try: + callback() + return True + except DoesNotExist as e: + if onerror: + onerror() + return False diff --git a/apps/backend/cart/schema.py b/apps/backend/cart/schema.py index 5c5373d..5128c01 100644 --- a/apps/backend/cart/schema.py +++ b/apps/backend/cart/schema.py @@ -13,25 +13,6 @@ from .cart import Cart from .models import PersistentCart -# class CartProductType(graphene.ObjectType): -# product=graphene.Field(ProductType) -# price=graphene.Int() -# variation=graphene.Field(VariationType) -# quantity=graphene.Int() -# total_price=graphene.Int() - - -# def resolve_total_price(parent): - -# # print("self",self,info) -# return parent["quantity"] * parent["price"] - - -# class CartType(graphene.ObjectType): -# cartLength=graphene.Int() -# totalPrice=graphene.Int() -# products=graphene.List(CartProductType) - class CartProductType(graphene.ObjectType): product = graphene.Field(ProductType) @@ -67,7 +48,7 @@ def resolve_cart(self, info, **kwargs): length = cart_.total_items() total_price = cart_.get_total_price() cart_products = cart_.products() - print(cart_products) + print("products", cart_products) return CartType( cartLength=length, totalPrice=total_price, products=cart_products ) @@ -147,6 +128,7 @@ def mutate(root, info, Input): else: cart = Cart(info.context) if Input.quantity <= 0: + cart.remove(product_id=Input.product_id, variation_id=Input.variation_id) else: cart.add( diff --git a/apps/backend/checkout/checkout.py b/apps/backend/checkout/checkout.py index 0a601cd..145898b 100644 --- a/apps/backend/checkout/checkout.py +++ b/apps/backend/checkout/checkout.py @@ -1,45 +1,47 @@ import stripe from django.conf import settings -from Orders.models import Order,OrderItem +from Orders.models import Order, OrderItem + def create_checkout_session(request): if request: - domain_url = 'http://localhost:8000/' + domain_url = "http://localhost:8000/" stripe.api_key = settings.STRIPE_SECRET_KEY try: - + checkout_session = stripe.checkout.Session.create( - success_url=domain_url + 'success?session_id={CHECKOUT_SESSION_ID}', - cancel_url=domain_url + 'cancelled/', - payment_method_types=['card'], - mode='payment', + success_url=domain_url + "success?session_id={CHECKOUT_SESSION_ID}", + cancel_url=domain_url + "cancelled/", + payment_method_types=["card"], + mode="payment", line_items=[ { - 'name': 'T-shirt', - 'quantity': 1, - 'currency': 'usd', - 'amount': '2000', + "name": "T-shirt", + "quantity": 1, + "currency": "usd", + "amount": "2000", } - ] + ], ) - return checkout_session['id'] + return checkout_session["id"] except Exception as e: - return str(e) + return str(e) + def create_payment_intent(order_id): - stripe.api_key=settings.STRIPE_SECRET_KEY + stripe.api_key = settings.STRIPE_SECRET_KEY print(stripe.api_key) - order=Order.objects.get(id=order_id) - #print("order_id",order_id) - total_price=order.total_amount() *100 - print("total_price in paisa",total_price) - intent=stripe.PaymentIntent.create( + order = Order.objects.get(id=order_id) + # print("order_id",order_id) + total_price = int(order.total_amount * 100) + print("total_price in paisa", total_price) + intent = stripe.PaymentIntent.create( amount=total_price, - currency='inr', + currency="inr", # payment_method_types=['card'], - automatic_payment_methods = {"enabled": True}, - ) - order.payment_id=intent['id'] + automatic_payment_methods={"enabled": True}, + ) + order.payment_id = intent["id"] order.save() - #print("intent",intent) + # print("intent",intent) return intent diff --git a/apps/backend/shop/models.py b/apps/backend/shop/models.py index 07e99c1..b30f987 100644 --- a/apps/backend/shop/models.py +++ b/apps/backend/shop/models.py @@ -110,9 +110,13 @@ def available_variants(self): return variants def filterby(self, data): # usually the input from graphene schema i.e FilterInput - filter = {"status": data["status"]} + filter = {} + print(data) + if data.status: + filter["status"] = data["status"] + if data.categories: filter["category__in"] = data.categories diff --git a/apps/backend/shop/schema.py b/apps/backend/shop/schema.py index 7674dd6..ac6c67f 100644 --- a/apps/backend/shop/schema.py +++ b/apps/backend/shop/schema.py @@ -27,8 +27,8 @@ def resolve_Products(self, info, filter={}, pageNb=1, **kwargs): # print("fetching products") # print("pagenb :- ",pageNb) - # if not info.context.user.is_superuser: - # filter["status"] = "active" + if not info.context.user.is_superuser: + filter["status"] = "active" limit = 30 offset = (pageNb - 1) * limit diff --git a/apps/backend/utils.py b/apps/backend/utils.py new file mode 100644 index 0000000..f409f46 --- /dev/null +++ b/apps/backend/utils.py @@ -0,0 +1,12 @@ +import graphene +import graphene.relay as relay + + +class CountableConnectionBase(relay.Connection): + class Meta: + abstract = True + + total_items = graphene.Int() + + def resolve_total_items(self, *args, **kwargs): + return self.length diff --git a/apps/frontend/admin/package.json b/apps/frontend/admin/package.json index 6b8bcc6..a0b4496 100644 --- a/apps/frontend/admin/package.json +++ b/apps/frontend/admin/package.json @@ -24,7 +24,7 @@ "graphql-tag": "^2.12.6", "router": "^2.0.0-beta.1", "utils": "*", - "vue": "^3.2.25", + "vue": "~3.2.25", "vue-chart-3": "^3.0.9", "vue-router": "4", "vuex": "4" @@ -41,6 +41,7 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-vue": "^8.4.0", "postcss": "^8.4.5", + "sass": "^1.49.7", "tailwindcss": "^3.0.15", "vite": "^2.7.2" } diff --git a/apps/frontend/admin/src/components/AppCard.vue b/apps/frontend/admin/src/components/AppCard.vue index 0a6855e..e2472c8 100644 --- a/apps/frontend/admin/src/components/AppCard.vue +++ b/apps/frontend/admin/src/components/AppCard.vue @@ -3,7 +3,7 @@ :is="$props.tag" class="bg-white" :class="[ - $props.outlined ? 'border-2' : 'border-none', + $props.outlined ? 'border' : 'border-none', `shadow-${$props.elevation}`, $props.tile ? 'rounded-none' : `rounded-${$props.rounded}`, diff --git a/apps/frontend/admin/src/components/AppSideBar.vue b/apps/frontend/admin/src/components/AppSideBar.vue index 762f256..00e6a87 100644 --- a/apps/frontend/admin/src/components/AppSideBar.vue +++ b/apps/frontend/admin/src/components/AppSideBar.vue @@ -35,7 +35,7 @@ const menuItems = { }, }, customers: { - to: { name: 'products' }, + to: { name: 'customers-all' }, icon: 'user', submenu: true, }, @@ -69,7 +69,7 @@ const route = useRoute()