fix: Letzshop page improvements - products, jobs, and tabs
1. Products tab now shows Letzshop marketplace products instead of vendor products - Uses /admin/products endpoint with marketplace=Letzshop filter - Fixed field names (image_link, price_numeric, sku vs vendor_sku) - Search now works with title, GTIN, SKU, brand 2. Jobs section moved to a separate tab - New "Jobs" tab between Exceptions and Settings - Tab watcher reloads data when switching tabs - Updated filter dropdown (removed export, added historical_import) 3. Product stats endpoint now accepts marketplace and vendor_name filters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -681,36 +681,59 @@ class MarketplaceProductService:
|
||||
|
||||
return result, total
|
||||
|
||||
def get_admin_product_stats(self, db: Session) -> dict:
|
||||
"""Get product statistics for admin dashboard."""
|
||||
def get_admin_product_stats(
|
||||
self,
|
||||
db: Session,
|
||||
marketplace: str | None = None,
|
||||
vendor_name: str | None = None,
|
||||
) -> dict:
|
||||
"""Get product statistics for admin dashboard.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
marketplace: Optional filter by marketplace (e.g., 'Letzshop')
|
||||
vendor_name: Optional filter by vendor name
|
||||
"""
|
||||
from sqlalchemy import func
|
||||
|
||||
total = db.query(func.count(MarketplaceProduct.id)).scalar() or 0
|
||||
# Build base filter
|
||||
base_filters = []
|
||||
if marketplace:
|
||||
base_filters.append(MarketplaceProduct.marketplace == marketplace)
|
||||
if vendor_name:
|
||||
base_filters.append(MarketplaceProduct.vendor_name == vendor_name)
|
||||
|
||||
active = (
|
||||
db.query(func.count(MarketplaceProduct.id))
|
||||
.filter(MarketplaceProduct.is_active == True) # noqa: E712
|
||||
.scalar()
|
||||
or 0
|
||||
base_query = db.query(func.count(MarketplaceProduct.id))
|
||||
if base_filters:
|
||||
base_query = base_query.filter(*base_filters)
|
||||
|
||||
total = base_query.scalar() or 0
|
||||
|
||||
active_query = db.query(func.count(MarketplaceProduct.id)).filter(
|
||||
MarketplaceProduct.is_active == True # noqa: E712
|
||||
)
|
||||
if base_filters:
|
||||
active_query = active_query.filter(*base_filters)
|
||||
active = active_query.scalar() or 0
|
||||
inactive = total - active
|
||||
|
||||
digital = (
|
||||
db.query(func.count(MarketplaceProduct.id))
|
||||
.filter(MarketplaceProduct.is_digital == True) # noqa: E712
|
||||
.scalar()
|
||||
or 0
|
||||
digital_query = db.query(func.count(MarketplaceProduct.id)).filter(
|
||||
MarketplaceProduct.is_digital == True # noqa: E712
|
||||
)
|
||||
if base_filters:
|
||||
digital_query = digital_query.filter(*base_filters)
|
||||
digital = digital_query.scalar() or 0
|
||||
physical = total - digital
|
||||
|
||||
marketplace_counts = (
|
||||
db.query(
|
||||
MarketplaceProduct.marketplace,
|
||||
func.count(MarketplaceProduct.id),
|
||||
)
|
||||
.group_by(MarketplaceProduct.marketplace)
|
||||
.all()
|
||||
marketplace_query = db.query(
|
||||
MarketplaceProduct.marketplace,
|
||||
func.count(MarketplaceProduct.id),
|
||||
)
|
||||
if base_filters:
|
||||
marketplace_query = marketplace_query.filter(*base_filters)
|
||||
marketplace_counts = marketplace_query.group_by(
|
||||
MarketplaceProduct.marketplace
|
||||
).all()
|
||||
by_marketplace = {mp or "unknown": count for mp, count in marketplace_counts}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user