From 0ed82854d9ee9a302bac634871aee1b1723d174d Mon Sep 17 00:00:00 2001 From: husanjon Date: Mon, 13 Apr 2026 17:24:50 +0500 Subject: [PATCH] restore composer.json, add mysqli extension --- .../vendor_product/VendorProduct.py | 45 ++++++++++++++++- core/apps/vendors/urls.py | 3 +- core/apps/vendors/views/Attribute.py | 15 ++++++ core/apps/vendors/views/__init__.py | 1 + scratch/explore_attributes_full.py | 48 +++++++++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 core/apps/vendors/views/Attribute.py create mode 100644 scratch/explore_attributes_full.py diff --git a/core/apps/vendors/serializers/vendor_product/VendorProduct.py b/core/apps/vendors/serializers/vendor_product/VendorProduct.py index 8108fb8..6f5067f 100644 --- a/core/apps/vendors/serializers/vendor_product/VendorProduct.py +++ b/core/apps/vendors/serializers/vendor_product/VendorProduct.py @@ -1,15 +1,56 @@ from rest_framework import serializers -from core.apps.vendors.models import VendorproductModel, VendorModel, CategoryModel, SectionModel +from core.apps.vendors.models import ( + VendorproductModel, + VendorModel, + CategoryModel, + SectionModel, + ProductVariantModel, + ProductAttributeModel +) from core.apps.vendors.serializers.vendor_product.ProductImage import ListProductimageSerializer +class ProductVariantSerializer(serializers.ModelSerializer): + class Meta: + model = ProductVariantModel + fields = [ + "id", + "firestore_id", + "price", + "sku", + "quantity", + "image_url", + "attribute_data", + ] + + def to_representation(self, instance): + ret = super().to_representation(instance) + attr_data = ret.get("attribute_data") + + if attr_data and isinstance(attr_data, list): + # Resolve attribute names + resolved_data = [] + for item in attr_data: + if isinstance(item, dict): + a_id = item.get("attribute_id") + if a_id: + # Try to get the name from the cache or DB + attr_obj = ProductAttributeModel.objects.filter(firestore_id=a_id).first() + item["attribute_name"] = attr_obj.name if attr_obj else "Unknown" + resolved_data.append(item) + ret["attribute_data"] = resolved_data + + return ret + + class BaseVendorproductSerializer(serializers.ModelSerializer): category = serializers.SlugRelatedField(slug_field='firestore_id', queryset=CategoryModel.objects.all(), required=False, allow_null=True) section = serializers.SlugRelatedField(slug_field='firestore_id', queryset=SectionModel.objects.all(), required=False, allow_null=True) images = ListProductimageSerializer(many=True, read_only=True) + variants = ProductVariantSerializer(many=True, read_only=True) class Meta: model = VendorproductModel @@ -27,7 +68,9 @@ class BaseVendorproductSerializer(serializers.ModelSerializer): "is_publish", "image", "images", + "variants", "photos_json", + "product_specification", ] def to_representation(self, instance): diff --git a/core/apps/vendors/urls.py b/core/apps/vendors/urls.py index f3f9211..0570c53 100644 --- a/core/apps/vendors/urls.py +++ b/core/apps/vendors/urls.py @@ -1,7 +1,7 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter -from .views import CategoryView, ProductimageView, VendorproductView, VendorView, SectionView +from .views import CategoryView, ProductimageView, VendorproductView, VendorView, SectionView, ProductAttributeView router = DefaultRouter() router.register("sections", SectionView, basename="sections") @@ -9,4 +9,5 @@ router.register("categories", CategoryView, basename="categories") router.register("vendors", VendorView, basename="vendors") router.register("products", VendorproductView, basename="products") router.register("product-images", ProductimageView, basename="product-images") +router.register("attributes", ProductAttributeView, basename="attributes") urlpatterns = [path("", include(router.urls))] diff --git a/core/apps/vendors/views/Attribute.py b/core/apps/vendors/views/Attribute.py new file mode 100644 index 0000000..a8db75a --- /dev/null +++ b/core/apps/vendors/views/Attribute.py @@ -0,0 +1,15 @@ +from rest_framework import viewsets, permissions +from core.apps.vendors.models import ProductAttributeModel +from rest_framework import serializers + + +class ProductAttributeSerializer(serializers.ModelSerializer): + class Meta: + model = ProductAttributeModel + fields = ["id", "firestore_id", "name"] + + +class ProductAttributeView(viewsets.ReadOnlyModelViewSet): + queryset = ProductAttributeModel.objects.all() + serializer_class = ProductAttributeSerializer + permission_classes = [permissions.AllowAny] diff --git a/core/apps/vendors/views/__init__.py b/core/apps/vendors/views/__init__.py index 8dc7430..fce87e7 100644 --- a/core/apps/vendors/views/__init__.py +++ b/core/apps/vendors/views/__init__.py @@ -2,3 +2,4 @@ from .category import * # noqa from .vendor import * # noqa from .vendor_product import * # noqa from .section import * # noqa +from .Attribute import * # noqa diff --git a/scratch/explore_attributes_full.py b/scratch/explore_attributes_full.py new file mode 100644 index 0000000..e086c31 --- /dev/null +++ b/scratch/explore_attributes_full.py @@ -0,0 +1,48 @@ +import firebase_admin +from firebase_admin import credentials, firestore +import os + +cert_path = 'fondexuzb-firebase-adminsdk-fbsvc-7b0e2d6200.json' +cred = credentials.Certificate(cert_path) +if not firebase_admin._apps: + firebase_admin.initialize_app(cred) +db = firestore.client() + +def explore(): + # 1. Vendor Attributes + v_attrs = list(db.collection('vendor_attributes').stream()) + v_attr_ids = {doc.id for doc in v_attrs} + print(f"Total vendor_attributes: {len(v_attrs)}") + for doc in v_attrs: + print(f" - {doc.id}: {doc.to_dict().get('title')}") + + # 2. Review Attributes + r_attrs = list(db.collection('review_attributes').stream()) + print(f"Total review_attributes: {len(r_attrs)}") + + # 3. Check for other potential collections + all_collections = [c.id for c in db.collections()] + keyword_matches = [c for c in all_collections if any(k in c.lower() for k in ['attr', 'option', 'variant', 'spec', 'prop'])] + print(f"Collections matching keywords: {keyword_matches}") + + # 4. Cross-reference with products + print("\nChecking products for missing attribute IDs...") + products = db.collection('vendor_products').limit(100).stream() + missing_ids = set() + for product in products: + data = product.to_dict() + item_attr = data.get('item_attribute') + if item_attr and isinstance(item_attr, dict): + attrs = item_attr.get('attributes') or [] + for a in attrs: + a_id = a.get('attribute_id') + if a_id and a_id not in v_attr_ids: + missing_ids.add(a_id) + + if missing_ids: + print(f"Found {len(missing_ids)} attribute IDs used in products but NOT in vendor_attributes: {missing_ids}") + else: + print("All attribute IDs found in products are accounted for in vendor_attributes.") + +if __name__ == "__main__": + explore()