seller_central_backend/api/sku_generator.py
vickytechkey b0f98e5702
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 33s
feat: add SKU generator utility for products with category and merchant mapping
2026-11-01 15:56:59 +05:30

100 lines
3.1 KiB
Python

import re
import logging
logger = logging.getLogger('api')
CATEGORY_CODES = {
'Food & Beverages': 'FNB',
'Personal Care': 'PCR',
'Hygiene & Reusable Care': 'HYG',
'Clothing & Textiles': 'TEX',
'Bags, Footwear & Leather': 'LEA',
'Jewellery': 'JWL',
'Home Decor & Furnishings': 'DEC',
'Kitchen & Dining': 'KIT',
'Eco Packaging & Disposables': 'PKG',
'Handicrafts & Folk Art': 'ART',
'Wooden, Bamboo & Coir Products': 'WOD',
'Toys & Games': 'TOY',
'Baby & Kids': 'KID',
'Pet Products': 'PET',
'Eco Cleaning Products': 'CLN',
'Farm, Garden & Compost': 'GRD',
'Stationery, Office & Tech': 'STN',
'Engineering & Manufactured Goods': 'ENG',
# Legacy categories mapped to official codes
'Handicrafts & Art': 'ART',
'Handloom & Textiles': 'TEX',
'Home & Living': 'DEC',
'Food & Organic': 'FNB',
'Beauty & Herbs': 'PCR',
'Toys & Folk Art': 'TOY',
'Pottery & Ceramics': 'ART',
'Brass & Metal Craft': 'ART',
'Woodcraft & Carvings': 'WOD',
'Apparel': 'TEX',
'Sculptures': 'ART',
'Kitchenware': 'KIT',
'Textiles': 'TEX',
}
def get_category_code(category_name):
"""
Returns the standardized 3-letter uppercase category code.
"""
if not category_name:
return 'GEN'
clean = str(category_name).strip()
if clean in CATEGORY_CODES:
return CATEGORY_CODES[clean]
lower = clean.lower()
for cat, code in CATEGORY_CODES.items():
if cat.lower() == lower or cat.lower() in lower or lower in cat.lower():
return code
alnum = re.sub(r'[^A-Z0-9]', '', clean.upper())
return (alnum[:3] if len(alnum) >= 3 else alnum.ljust(3, 'X'))
def normalize_merchant_id(user):
"""
Extracts and standardizes the seller's Merchant ID (TRDPX000001 format).
"""
if not user:
return 'TRDPX000001'
profile = getattr(user, 'profile', None)
mid = getattr(profile, 'merchant_id', None)
if not mid:
draft = getattr(user, 'onboarding_draft', None)
mid = getattr(draft, 'merchant_id', None)
if mid and str(mid).strip():
return str(mid).strip().upper().replace(' ', '')
user_id = getattr(user, 'id', 1)
return f"TRDPX{str(user_id).zfill(6)}"
def generate_product_sku(user, category_name=None, product_model=None):
"""
Generates a unique SKU in format: TRDX-[categorycode]-[sellermid]-[productsno]
e.g. TRDX-TEX-TRDPX000042-001
"""
if product_model is None:
from .models import Product
product_model = Product
cat_code = get_category_code(category_name)
mid = normalize_merchant_id(user)
user_product_count = product_model.objects.filter(supplier=user).count() if user else 0
seq = user_product_count + 1
candidate_sku = f"TRDX-{cat_code}-{mid}-{seq:03d}"
while product_model.objects.filter(sku=candidate_sku).exists():
seq += 1
candidate_sku = f"TRDX-{cat_code}-{mid}-{seq:03d}"
logger.info("Generated SKU: %s for user=%s category=%s", candidate_sku, getattr(user, 'username', 'anon'), category_name)
return candidate_sku