feat: add configurable currency locale and fix vendor JS init
Currency Locale Configuration: - Add platform-level storefront settings (locale, currency) - Create PlatformSettingsService with resolution chain: vendor → AdminSetting → environment → hardcoded fallback - Add storefront_locale nullable field to Vendor model - Update shop routes to resolve and pass locale to templates - Add window.SHOP_CONFIG for frontend JavaScript access - Centralize formatPrice() in shop-layout.js using SHOP_CONFIG - Remove local formatPrice functions from shop templates Vendor JS Bug Fix: - Fix vendorCode being null on all vendor pages - Root cause: page components overriding init() without calling parent - Add parent init call to 14 vendor JS files - Add JS-013 architecture rule to prevent future regressions - Validator now checks vendor JS files for parent init pattern Files changed: - New: app/services/platform_settings_service.py - New: alembic/versions/s7a8b9c0d1e2_add_storefront_locale_to_vendors.py - Modified: 14 vendor JS files, shop templates, validation scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_customer_from_cookie_or_header, get_db
|
||||
from app.services.content_page_service import content_page_service
|
||||
from app.services.platform_settings_service import platform_settings_service
|
||||
from models.database.customer import Customer
|
||||
|
||||
router = APIRouter()
|
||||
@@ -47,6 +48,40 @@ templates = Jinja2Templates(directory="app/templates")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# HELPER: Resolve Storefront Locale
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def get_resolved_storefront_config(db: Session, vendor) -> dict:
|
||||
"""
|
||||
Resolve storefront locale and currency with priority:
|
||||
1. Vendor's storefront_locale (if set)
|
||||
2. Platform's default_storefront_locale (from AdminSetting)
|
||||
3. Environment variable (from config)
|
||||
4. Hardcoded fallback: 'fr-LU'
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor: Vendor model instance
|
||||
|
||||
Returns:
|
||||
dict with 'locale' and 'currency' keys
|
||||
"""
|
||||
# Get platform defaults from service (handles resolution chain 2-4)
|
||||
platform_config = platform_settings_service.get_storefront_config(db)
|
||||
|
||||
# Check for vendor override (step 1)
|
||||
locale = platform_config["locale"]
|
||||
if vendor and vendor.storefront_locale:
|
||||
locale = vendor.storefront_locale
|
||||
|
||||
return {
|
||||
"locale": locale,
|
||||
"currency": platform_config["currency"],
|
||||
}
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# HELPER: Build Shop Template Context
|
||||
# ============================================================================
|
||||
@@ -133,6 +168,11 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
extra={"error": str(e), "vendor_id": vendor.id if vendor else None},
|
||||
)
|
||||
|
||||
# Resolve storefront locale and currency
|
||||
storefront_config = {"locale": "fr-LU", "currency": "EUR"} # defaults
|
||||
if db and vendor:
|
||||
storefront_config = get_resolved_storefront_config(db, vendor)
|
||||
|
||||
context = {
|
||||
"request": request,
|
||||
"vendor": vendor,
|
||||
@@ -142,6 +182,8 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
"base_url": base_url,
|
||||
"footer_pages": footer_pages,
|
||||
"header_pages": header_pages,
|
||||
"storefront_locale": storefront_config["locale"],
|
||||
"storefront_currency": storefront_config["currency"],
|
||||
}
|
||||
|
||||
# Add any extra context (user, product_id, category_slug, etc.)
|
||||
@@ -157,6 +199,8 @@ def get_shop_context(request: Request, db: Session = None, **extra_context) -> d
|
||||
"has_theme": theme is not None,
|
||||
"access_method": access_method,
|
||||
"base_url": base_url,
|
||||
"storefront_locale": storefront_config["locale"],
|
||||
"storefront_currency": storefront_config["currency"],
|
||||
"footer_pages_count": len(footer_pages),
|
||||
"header_pages_count": len(header_pages),
|
||||
"extra_keys": list(extra_context.keys()) if extra_context else [],
|
||||
|
||||
Reference in New Issue
Block a user