feat: add unified admin Marketplace Letzshop page
- Add new Marketplace section in admin sidebar with Letzshop sub-item
- Remove old Import and Letzshop Orders items from Product Catalog
- Create unified Letzshop management page with 3 tabs:
- Products tab: Import/Export functionality
- Orders tab: Order management with confirm/reject/tracking
- Settings tab: API credentials and CSV URLs
- Add unified jobs table showing imports, exports, and order syncs
- Implement vendor autocomplete using Tom Select library (CDN + fallback)
- Add /vendors/{vendor_id}/jobs API endpoint for unified job listing
- Move database queries to service layer (LetzshopOrderService)
- Add LetzshopJobItem and LetzshopJobsListResponse schemas
- Include Tom Select CSS/JS assets as local fallback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,8 @@ from models.schema.letzshop import (
|
||||
LetzshopCredentialsCreate,
|
||||
LetzshopCredentialsResponse,
|
||||
LetzshopCredentialsUpdate,
|
||||
LetzshopJobItem,
|
||||
LetzshopJobsListResponse,
|
||||
LetzshopOrderListResponse,
|
||||
LetzshopOrderResponse,
|
||||
LetzshopSuccessResponse,
|
||||
@@ -478,3 +480,47 @@ def trigger_vendor_sync(
|
||||
message=f"Sync failed: {e}",
|
||||
errors=[str(e)],
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Jobs (Unified view of imports, exports, and syncs)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get(
|
||||
"/vendors/{vendor_id}/jobs",
|
||||
response_model=LetzshopJobsListResponse,
|
||||
)
|
||||
def list_vendor_letzshop_jobs(
|
||||
vendor_id: int = Path(..., description="Vendor ID"),
|
||||
job_type: str | None = Query(None, description="Filter: import, export, order_sync"),
|
||||
status: str | None = Query(None, description="Filter by status"),
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: User = Depends(get_current_admin_api),
|
||||
):
|
||||
"""
|
||||
Get unified list of Letzshop-related jobs for a vendor.
|
||||
Combines product imports, exports, and order syncs.
|
||||
"""
|
||||
order_service = get_order_service(db)
|
||||
|
||||
try:
|
||||
order_service.get_vendor_or_raise(vendor_id)
|
||||
except VendorNotFoundError:
|
||||
raise ResourceNotFoundException("Vendor", str(vendor_id))
|
||||
|
||||
# Use service layer for database queries
|
||||
jobs_data, total = order_service.list_letzshop_jobs(
|
||||
vendor_id=vendor_id,
|
||||
job_type=job_type,
|
||||
status=status,
|
||||
skip=skip,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
# Convert dict data to Pydantic models
|
||||
jobs = [LetzshopJobItem(**job) for job in jobs_data]
|
||||
|
||||
return LetzshopJobsListResponse(jobs=jobs, total=total)
|
||||
|
||||
Reference in New Issue
Block a user