Features: 1) Add # noinspection PyUnusedLocal annotations to various viewsets, filters, and migrations to suppress unnecessary warnings; 2) Improve post method in BusinessPurchaseView to handle exceptions and inactive orders gracefully; 3) Refactor resolve_transactions and related resolvers in Graphene to include more specific typing hints; 4) Include defensive coding for attributes in several models to ensure type safety.
Fixes: 1) Correct default manager assignment in `Product` model; 2) Address potential division by zero in `AbsoluteFTPStorage`; 3) Ensure proper exception handling for missing `order` attributes in CRM gateway methods; 4) Rectify inaccurate string formatting for `Transaction` `__str__` method. Extra: Refactor various minor code style issues, including formatting corrections in the README, alignment in the emailing utility, and suppressed pycharm-specific inspections; clean up unused imports across files; enhance error messaging consistency.
This commit is contained in:
parent
91ed79669b
commit
330177f6e4
17 changed files with 92 additions and 37 deletions
|
|
@ -100,7 +100,7 @@ before running installment scripts
|
||||||
### nginx
|
### nginx
|
||||||
|
|
||||||
Please comment-out SSL-related lines, then apply necessary configurations, run `certbot --cert-only --nginx`,
|
Please comment-out SSL-related lines, then apply necessary configurations, run `certbot --cert-only --nginx`,
|
||||||
decomment previously commented lines and enjoy eVibes over HTTPS!
|
decomment previously commented lines, and enjoy eVibes over HTTPS!
|
||||||
|
|
||||||
### .env
|
### .env
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,9 @@ class AmoCRM:
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
def _get_customer_name(self, order: Order) -> str:
|
def _get_customer_name(self, order: Order) -> str:
|
||||||
|
if type(order.attributes) is not dict:
|
||||||
|
raise ValueError("order.attributes must be a dict")
|
||||||
|
|
||||||
if not order.attributes.get("business_identificator"):
|
if not order.attributes.get("business_identificator"):
|
||||||
return (
|
return (
|
||||||
order.user.get_full_name()
|
order.user.get_full_name()
|
||||||
|
|
@ -142,6 +145,8 @@ class AmoCRM:
|
||||||
body = r.json()
|
body = r.json()
|
||||||
return body.get("_embedded", {}).get("contacts", [{}])[0].get("id", None)
|
return body.get("_embedded", {}).get("contacts", [{}])[0].get("id", None)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -180,5 +185,5 @@ class AmoCRM:
|
||||||
|
|
||||||
if link.order.status == new_status:
|
if link.order.status == new_status:
|
||||||
return
|
return
|
||||||
link.order.status = self.STATUS_MAP.get(new_status)
|
link.order.status = self.STATUS_MAP[new_status]
|
||||||
link.order.save(update_fields=["status"])
|
link.order.save(update_fields=["status"])
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ class CaseInsensitiveListFilter(BaseInFilter, CharFilter):
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class ProductFilter(FilterSet):
|
class ProductFilter(FilterSet):
|
||||||
search = CharFilter(field_name="name", method="search_products", label=_("Search"))
|
search = CharFilter(field_name="name", method="search_products", label=_("Search"))
|
||||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
|
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))
|
||||||
|
|
@ -153,7 +154,7 @@ class ProductFilter(FilterSet):
|
||||||
if not value:
|
if not value:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
uuids = [product.get("uuid") for product in process_query(query=value, indexes=("products",))["products"]]
|
uuids = [product.get("uuid") for product in process_query(query=value, indexes=("products",))["products"]] # type: ignore
|
||||||
|
|
||||||
return queryset.filter(uuid__in=uuids)
|
return queryset.filter(uuid__in=uuids)
|
||||||
|
|
||||||
|
|
@ -396,6 +397,7 @@ class WishlistFilter(FilterSet):
|
||||||
fields = ["uuid", "user_email", "user", "order_by"]
|
fields = ["uuid", "user_email", "user", "order_by"]
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class CategoryFilter(FilterSet):
|
class CategoryFilter(FilterSet):
|
||||||
search = CharFilter(field_name="name", method="search_categories", label=_("Search"))
|
search = CharFilter(field_name="name", method="search_categories", label=_("Search"))
|
||||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
||||||
|
|
@ -429,7 +431,7 @@ class CategoryFilter(FilterSet):
|
||||||
if not value:
|
if not value:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
uuids = [category.get("uuid") for category in process_query(query=value, indexes=("categories",))["categories"]]
|
uuids = [category.get("uuid") for category in process_query(query=value, indexes=("categories",))["categories"]] # type: ignore
|
||||||
|
|
||||||
return queryset.filter(uuid__in=uuids)
|
return queryset.filter(uuid__in=uuids)
|
||||||
|
|
||||||
|
|
@ -522,6 +524,7 @@ class CategoryFilter(FilterSet):
|
||||||
return queryset.filter(parent__uuid=uuid_val)
|
return queryset.filter(parent__uuid=uuid_val)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class BrandFilter(FilterSet):
|
class BrandFilter(FilterSet):
|
||||||
search = CharFilter(field_name="name", method="search_brands", label=_("Search"))
|
search = CharFilter(field_name="name", method="search_brands", label=_("Search"))
|
||||||
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
|
||||||
|
|
@ -547,7 +550,7 @@ class BrandFilter(FilterSet):
|
||||||
if not value:
|
if not value:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
uuids = [brand.get("uuid") for brand in process_query(query=value, indexes=("brands",))["brands"]]
|
uuids = [brand.get("uuid") for brand in process_query(query=value, indexes=("brands",))["brands"]] # type: ignore
|
||||||
|
|
||||||
return queryset.filter(uuid__in=uuids)
|
return queryset.filter(uuid__in=uuids)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -546,6 +546,7 @@ class FeedbackProductAction(BaseMutation):
|
||||||
order_product = OrderProduct.objects.get(uuid=order_product_uuid)
|
order_product = OrderProduct.objects.get(uuid=order_product_uuid)
|
||||||
if user != order_product.order.user:
|
if user != order_product.order.user:
|
||||||
raise PermissionDenied(permission_denied_message)
|
raise PermissionDenied(permission_denied_message)
|
||||||
|
feedback = None
|
||||||
match action:
|
match action:
|
||||||
case "add":
|
case "add":
|
||||||
feedback = order_product.do_feedback(comment=comment, rating=rating, action="add")
|
feedback = order_product.do_feedback(comment=comment, rating=rating, action="add")
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from constance import config
|
from constance import config
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import Max, Min, QuerySet
|
from django.db.models import Max, Min
|
||||||
from django.db.models.functions import Length
|
from django.db.models.functions import Length
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from graphene import (
|
from graphene import (
|
||||||
|
|
@ -55,7 +56,6 @@ from core.utils.seo_builders import (
|
||||||
website_schema,
|
website_schema,
|
||||||
)
|
)
|
||||||
from payments.graphene.object_types import TransactionType
|
from payments.graphene.object_types import TransactionType
|
||||||
from payments.models import Transaction
|
|
||||||
|
|
||||||
logger = logging.getLogger("django")
|
logger = logging.getLogger("django")
|
||||||
|
|
||||||
|
|
@ -464,19 +464,19 @@ class OrderType(DjangoObjectType):
|
||||||
)
|
)
|
||||||
description = _("orders")
|
description = _("orders")
|
||||||
|
|
||||||
def resolve_total_price(self: Order, _info):
|
def resolve_total_price(self: Order, _info) -> float:
|
||||||
return self.total_price
|
return self.total_price
|
||||||
|
|
||||||
def resolve_total_quantity(self: Order, _info):
|
def resolve_total_quantity(self: Order, _info) -> int:
|
||||||
return self.total_quantity
|
return self.total_quantity
|
||||||
|
|
||||||
def resolve_notifications(self: Order, _info):
|
def resolve_notifications(self: Order, _info) -> dict[str, Any]:
|
||||||
return camelize(self.notifications)
|
return camelize(self.notifications)
|
||||||
|
|
||||||
def resolve_attributes(self: Order, _info):
|
def resolve_attributes(self: Order, _info) -> dict[str, Any]:
|
||||||
return camelize(self.attributes)
|
return camelize(self.attributes)
|
||||||
|
|
||||||
def resolve_payments_transactions(self: Order, _info) -> QuerySet[Transaction] | None:
|
def resolve_payments_transactions(self: Order, _info):
|
||||||
if self.payments_transactions:
|
if self.payments_transactions:
|
||||||
return self.payments_transactions.all()
|
return self.payments_transactions.all()
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ def generate_unique_sku(make_candidate, taken):
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def backfill_sku(apps, schema_editor):
|
def backfill_sku(apps, schema_editor):
|
||||||
Product = apps.get_model("core", "Product")
|
Product = apps.get_model("core", "Product")
|
||||||
from core.utils import generate_human_readable_id as make_candidate
|
from core.utils import generate_human_readable_id as make_candidate
|
||||||
|
|
@ -35,6 +36,7 @@ def backfill_sku(apps, schema_editor):
|
||||||
last_pk = ids[-1]
|
last_pk = ids[-1]
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def noop(apps, schema_editor):
|
def noop(apps, schema_editor):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,7 @@ class Product(ExportModelOperationsMixin("product"), NiceModel): # type: ignore
|
||||||
default=generate_human_readable_id,
|
default=generate_human_readable_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
objects: ProductManager = ProductManager()
|
objects = ProductManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("product")
|
verbose_name = _("product")
|
||||||
|
|
@ -1266,6 +1266,10 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_business(self) -> bool:
|
def is_business(self) -> bool:
|
||||||
|
if type(self.attributes) is not dict:
|
||||||
|
self.attributes = {}
|
||||||
|
self.save()
|
||||||
|
return False
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
return (self.attributes.get("is_business", False) if self.attributes else False) or (
|
return (self.attributes.get("is_business", False) if self.attributes else False) or (
|
||||||
(self.user.attributes.get("is_business", False) and self.user.attributes.get("business_identificator"))
|
(self.user.attributes.get("is_business", False) and self.user.attributes.get("business_identificator"))
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ class CategoryDetailSerializer(ModelSerializer):
|
||||||
|
|
||||||
filterable_results = []
|
filterable_results = []
|
||||||
for attr in attributes:
|
for attr in attributes:
|
||||||
vals = grouped.get(attr.id, [])
|
vals = grouped.get(attr.id, []) # type: ignore
|
||||||
slice_vals = vals[:128] if len(vals) > 128 else vals
|
slice_vals = vals[:128] if len(vals) > 128 else vals
|
||||||
filterable_results.append(
|
filterable_results.append(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,20 @@ def send_order_created_email(order_pk: str) -> tuple[bool, str]:
|
||||||
except Order.DoesNotExist:
|
except Order.DoesNotExist:
|
||||||
return False, f"Order not found with the given pk: {order_pk}"
|
return False, f"Order not found with the given pk: {order_pk}"
|
||||||
|
|
||||||
|
if type(order.attributes) is not dict:
|
||||||
|
order.attributes = {}
|
||||||
|
|
||||||
if not any([order.user, order.attributes.get("email", None), order.attributes.get("customer_email", None)]):
|
if not any([order.user, order.attributes.get("email", None), order.attributes.get("customer_email", None)]):
|
||||||
return False, f"Order's user not found with the given pk: {order_pk}"
|
return False, f"Order's user not found with the given pk: {order_pk}"
|
||||||
|
|
||||||
activate(order.user.language)
|
language = settings.LANGUAGE_CODE
|
||||||
|
recipient = order.attributes.get("customer_email", "")
|
||||||
|
|
||||||
|
if order.user:
|
||||||
|
recipient = order.user.email
|
||||||
|
language = order.user.language
|
||||||
|
|
||||||
|
activate(language)
|
||||||
|
|
||||||
set_email_settings()
|
set_email_settings()
|
||||||
connection = mail.get_connection()
|
connection = mail.get_connection()
|
||||||
|
|
@ -71,7 +81,7 @@ def send_order_created_email(order_pk: str) -> tuple[bool, str]:
|
||||||
"total_price": order.total_price,
|
"total_price": order.total_price,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
to=[order.user.email],
|
to=[recipient],
|
||||||
from_email=f"{config.PROJECT_NAME} <{config.EMAIL_FROM}>",
|
from_email=f"{config.PROJECT_NAME} <{config.EMAIL_FROM}>",
|
||||||
connection=connection,
|
connection=connection,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
2
core/vendors/__init__.py
vendored
2
core/vendors/__init__.py
vendored
|
|
@ -235,7 +235,7 @@ class AbstractVendor:
|
||||||
if not rate:
|
if not rate:
|
||||||
raise RatesError(f"No rate found for {currency or self.currency} in {rates} with probider {provider}...")
|
raise RatesError(f"No rate found for {currency or self.currency} in {rates} with probider {provider}...")
|
||||||
|
|
||||||
return float(round(price / rate, 2)) if rate else float(round(price, 2))
|
return float(round(price / rate, 2)) if rate else round(price, 2)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def round_price_marketologically(price: float) -> float:
|
def round_price_marketologically(price: float) -> float:
|
||||||
|
|
|
||||||
|
|
@ -428,27 +428,35 @@ class BuyAsBusinessView(APIView):
|
||||||
Handles the "POST" request to process a business purchase.
|
Handles the "POST" request to process a business purchase.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@method_decorator(ratelimit(key="ip", rate="2/h", block=True))
|
@method_decorator(ratelimit(key="ip", rate="10/h", block=True))
|
||||||
def post(self, request, *_args, **kwargs):
|
def post(self, request, *_args, **kwargs):
|
||||||
serializer = BuyAsBusinessOrderSerializer(data=request.data)
|
serializer = BuyAsBusinessOrderSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
order = Order.objects.create(status="MOMENTAL")
|
order = Order.objects.create(status="MOMENTAL")
|
||||||
products = [product.get("product_uuid") for product in serializer.validated_data.get("products")]
|
products = [product.get("product_uuid") for product in serializer.validated_data.get("products")]
|
||||||
transaction = order.buy_without_registration(
|
try:
|
||||||
products=products,
|
transaction = order.buy_without_registration(
|
||||||
promocode_uuid=serializer.validated_data.get("promocode_uuid"),
|
products=products,
|
||||||
customer_name=serializer.validated_data.get("business_identificator"),
|
promocode_uuid=serializer.validated_data.get("promocode_uuid"),
|
||||||
customer_email=serializer.validated_data.get("business_email"),
|
customer_name=serializer.validated_data.get("business_identificator"),
|
||||||
customer_phone_number=serializer.validated_data.get("business_phone_number"),
|
customer_email=serializer.validated_data.get("business_email"),
|
||||||
billing_customer_address=serializer.validated_data.get("billing_business_address_uuid"),
|
customer_phone_number=serializer.validated_data.get("business_phone_number"),
|
||||||
shipping_customer_address=serializer.validated_data.get("shipping_business_address_uuid"),
|
billing_customer_address=serializer.validated_data.get("billing_business_address_uuid"),
|
||||||
payment_method=serializer.validated_data.get("payment_method"),
|
shipping_customer_address=serializer.validated_data.get("shipping_business_address_uuid"),
|
||||||
is_business=True,
|
payment_method=serializer.validated_data.get("payment_method"),
|
||||||
)
|
is_business=True,
|
||||||
return Response(
|
)
|
||||||
status=status.HTTP_201_CREATED,
|
return Response(
|
||||||
data=TransactionProcessSerializer(transaction).data,
|
status=status.HTTP_201_CREATED,
|
||||||
)
|
data=TransactionProcessSerializer(transaction).data,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
order.is_active = False
|
||||||
|
order.save()
|
||||||
|
return Response(
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
data={"error": str(e)},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def download_digital_asset_view(request, *args, **kwargs):
|
def download_digital_asset_view(request, *args, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ class EvibesViewSet(ModelViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ATTRIBUTE_GROUP_SCHEMA)
|
@extend_schema_view(**ATTRIBUTE_GROUP_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class AttributeGroupViewSet(EvibesViewSet):
|
class AttributeGroupViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Represents a viewset for managing AttributeGroup objects.
|
Represents a viewset for managing AttributeGroup objects.
|
||||||
|
|
@ -187,6 +188,7 @@ class AttributeGroupViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ATTRIBUTE_SCHEMA)
|
@extend_schema_view(**ATTRIBUTE_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class AttributeViewSet(EvibesViewSet):
|
class AttributeViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Handles operations related to Attribute objects within the application.
|
Handles operations related to Attribute objects within the application.
|
||||||
|
|
@ -219,6 +221,7 @@ class AttributeViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ATTRIBUTE_VALUE_SCHEMA)
|
@extend_schema_view(**ATTRIBUTE_VALUE_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class AttributeValueViewSet(EvibesViewSet):
|
class AttributeValueViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
A viewset for managing AttributeValue objects.
|
A viewset for managing AttributeValue objects.
|
||||||
|
|
@ -247,6 +250,7 @@ class AttributeValueViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**CATEGORY_SCHEMA)
|
@extend_schema_view(**CATEGORY_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class CategoryViewSet(EvibesViewSet):
|
class CategoryViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Manages views for Category-related operations.
|
Manages views for Category-related operations.
|
||||||
|
|
@ -377,6 +381,7 @@ class CategoryViewSet(EvibesViewSet):
|
||||||
return Response(SeoSnapshotSerializer(payload).data)
|
return Response(SeoSnapshotSerializer(payload).data)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class BrandViewSet(EvibesViewSet):
|
class BrandViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Represents a viewset for managing Brand instances.
|
Represents a viewset for managing Brand instances.
|
||||||
|
|
@ -502,6 +507,7 @@ class BrandViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**PRODUCT_SCHEMA)
|
@extend_schema_view(**PRODUCT_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class ProductViewSet(EvibesViewSet):
|
class ProductViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Manages operations related to the `Product` model in the system.
|
Manages operations related to the `Product` model in the system.
|
||||||
|
|
@ -635,6 +641,7 @@ class ProductViewSet(EvibesViewSet):
|
||||||
return Response(SeoSnapshotSerializer(payload).data)
|
return Response(SeoSnapshotSerializer(payload).data)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class VendorViewSet(EvibesViewSet):
|
class VendorViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Represents a viewset for managing Vendor objects.
|
Represents a viewset for managing Vendor objects.
|
||||||
|
|
@ -666,6 +673,7 @@ class VendorViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**FEEDBACK_SCHEMA)
|
@extend_schema_view(**FEEDBACK_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class FeedbackViewSet(EvibesViewSet):
|
class FeedbackViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Representation of a view set handling Feedback objects.
|
Representation of a view set handling Feedback objects.
|
||||||
|
|
@ -704,6 +712,7 @@ class FeedbackViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ORDER_SCHEMA)
|
@extend_schema_view(**ORDER_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class OrderViewSet(EvibesViewSet):
|
class OrderViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
ViewSet for managing orders and related operations.
|
ViewSet for managing orders and related operations.
|
||||||
|
|
@ -921,6 +930,7 @@ class OrderViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ORDER_PRODUCT_SCHEMA)
|
@extend_schema_view(**ORDER_PRODUCT_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class OrderProductViewSet(EvibesViewSet):
|
class OrderProductViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Provides a viewset for managing OrderProduct entities.
|
Provides a viewset for managing OrderProduct entities.
|
||||||
|
|
@ -993,6 +1003,7 @@ class OrderProductViewSet(EvibesViewSet):
|
||||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class ProductImageViewSet(EvibesViewSet):
|
class ProductImageViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Manages operations related to Product images in the application.
|
Manages operations related to Product images in the application.
|
||||||
|
|
@ -1025,6 +1036,7 @@ class ProductImageViewSet(EvibesViewSet):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class PromoCodeViewSet(EvibesViewSet):
|
class PromoCodeViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Manages the retrieval and handling of PromoCode instances through various
|
Manages the retrieval and handling of PromoCode instances through various
|
||||||
|
|
@ -1064,6 +1076,7 @@ class PromoCodeViewSet(EvibesViewSet):
|
||||||
return qs.filter(user=user)
|
return qs.filter(user=user)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class PromotionViewSet(EvibesViewSet):
|
class PromotionViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Represents a view set for managing promotions.
|
Represents a view set for managing promotions.
|
||||||
|
|
@ -1083,6 +1096,7 @@ class PromotionViewSet(EvibesViewSet):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class StockViewSet(EvibesViewSet):
|
class StockViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Handles operations related to Stock data in the system.
|
Handles operations related to Stock data in the system.
|
||||||
|
|
@ -1115,6 +1129,7 @@ class StockViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**WISHLIST_SCHEMA)
|
@extend_schema_view(**WISHLIST_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class WishlistViewSet(EvibesViewSet):
|
class WishlistViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
ViewSet for managing Wishlist operations.
|
ViewSet for managing Wishlist operations.
|
||||||
|
|
@ -1254,6 +1269,7 @@ class WishlistViewSet(EvibesViewSet):
|
||||||
|
|
||||||
|
|
||||||
@extend_schema_view(**ADDRESS_SCHEMA)
|
@extend_schema_view(**ADDRESS_SCHEMA)
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class AddressViewSet(EvibesViewSet):
|
class AddressViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
This class provides viewset functionality for managing `Address` objects.
|
This class provides viewset functionality for managing `Address` objects.
|
||||||
|
|
@ -1329,6 +1345,7 @@ class AddressViewSet(EvibesViewSet):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
class ProductTagViewSet(EvibesViewSet):
|
class ProductTagViewSet(EvibesViewSet):
|
||||||
"""
|
"""
|
||||||
Handles operations related to Product Tags within the application.
|
Handles operations related to Product Tags within the application.
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from storages.backends.ftp import FTPStorage
|
||||||
|
|
||||||
class AbsoluteFTPStorage(FTPStorage): # type: ignore
|
class AbsoluteFTPStorage(FTPStorage): # type: ignore
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
|
||||||
def _get_config(self):
|
def _get_config(self):
|
||||||
cfg = super()._get_config()
|
cfg = super()._get_config()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import graphene
|
import graphene
|
||||||
from django.db.models import QuerySet
|
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
from graphene.types.generic import GenericScalar
|
from graphene.types.generic import GenericScalar
|
||||||
from graphene_django import DjangoObjectType
|
from graphene_django import DjangoObjectType
|
||||||
|
|
@ -32,7 +31,7 @@ class BalanceType(DjangoObjectType):
|
||||||
interfaces = (relay.Node,)
|
interfaces = (relay.Node,)
|
||||||
filter_fields = ["is_active"]
|
filter_fields = ["is_active"]
|
||||||
|
|
||||||
def resolve_transaction_set(self: Balance, info) -> QuerySet["Transaction"] | list:
|
def resolve_transactions(self: Balance, info) -> list:
|
||||||
if info.context.user == self.user:
|
if info.context.user == self.user:
|
||||||
# noinspection Mypy
|
# noinspection Mypy
|
||||||
return self.transactions.all() or []
|
return self.transactions.all() or []
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@ class Transaction(NiceModel):
|
||||||
process = JSONField(verbose_name=_("processing details"), default=dict)
|
process = JSONField(verbose_name=_("processing details"), default=dict)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.balance.user.email} | {self.amount}" if self.balance else\
|
return (
|
||||||
f"{self.order.attributes.get("customer_email")} | {self.amount}"
|
f"{self.balance.user.email} | {self.amount}"
|
||||||
|
if self.balance
|
||||||
|
else f"{self.order.attributes.get('customer_email')} | {self.amount}"
|
||||||
|
)
|
||||||
|
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
if self.amount != 0.0 and (
|
if self.amount != 0.0 and (
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ def create_balance_on_user_creation_signal(instance, created, **_kwargs):
|
||||||
def process_transaction_changes(instance, created, **_kwargs):
|
def process_transaction_changes(instance, created, **_kwargs):
|
||||||
if created:
|
if created:
|
||||||
try:
|
try:
|
||||||
|
gateway = None
|
||||||
match instance.process.get("gateway", "default"):
|
match instance.process.get("gateway", "default"):
|
||||||
case "gateway":
|
case "gateway":
|
||||||
gateway = AbstractGateway()
|
gateway = AbstractGateway()
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ from vibes_auth.utils.emailing import send_reset_password_email_task
|
||||||
logger = logging.getLogger("django")
|
logger = logging.getLogger("django")
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection GrazieInspection
|
||||||
@extend_schema_view(**USER_SCHEMA)
|
@extend_schema_view(**USER_SCHEMA)
|
||||||
class UserViewSet(
|
class UserViewSet(
|
||||||
mixins.CreateModelMixin,
|
mixins.CreateModelMixin,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue