feat: show Jobs tab for all vendors when no filter selected
- Add /admin/letzshop/jobs API endpoint for all jobs across vendors - Update list_letzshop_jobs service to support optional vendor_id - Remove x-if condition from Jobs tab button and panel - Update JS to use global or vendor-specific endpoint based on selection - Update jobs table subtitle to show context 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -607,29 +607,37 @@ class LetzshopOrderService:
|
||||
|
||||
def list_letzshop_jobs(
|
||||
self,
|
||||
vendor_id: int,
|
||||
vendor_id: int | None = None,
|
||||
job_type: str | None = None,
|
||||
status: str | None = None,
|
||||
skip: int = 0,
|
||||
limit: int = 20,
|
||||
) -> tuple[list[dict[str, Any]], int]:
|
||||
"""
|
||||
List unified Letzshop-related jobs for a vendor.
|
||||
List unified Letzshop-related jobs for a vendor or all vendors.
|
||||
|
||||
Combines product imports, historical order imports, and order syncs.
|
||||
If vendor_id is None, returns jobs across all vendors.
|
||||
"""
|
||||
jobs = []
|
||||
|
||||
# Fetch vendor info once for all jobs
|
||||
vendor = self.get_vendor(vendor_id)
|
||||
vendor_name = vendor.name if vendor else None
|
||||
vendor_code = vendor.vendor_code if vendor else None
|
||||
# Fetch vendor info - for single vendor or build lookup for all vendors
|
||||
if vendor_id:
|
||||
vendor = self.get_vendor(vendor_id)
|
||||
vendor_lookup = {vendor_id: (vendor.name if vendor else None, vendor.vendor_code if vendor else None)}
|
||||
else:
|
||||
# Build lookup for all vendors when showing all jobs
|
||||
from models.database.vendor import Vendor
|
||||
vendors = self.db.query(Vendor.id, Vendor.name, Vendor.vendor_code).all()
|
||||
vendor_lookup = {v.id: (v.name, v.vendor_code) for v in vendors}
|
||||
|
||||
# Historical order imports from letzshop_historical_import_jobs
|
||||
if job_type in (None, "historical_import"):
|
||||
hist_query = self.db.query(LetzshopHistoricalImportJob).filter(
|
||||
LetzshopHistoricalImportJob.vendor_id == vendor_id,
|
||||
)
|
||||
hist_query = self.db.query(LetzshopHistoricalImportJob)
|
||||
if vendor_id:
|
||||
hist_query = hist_query.filter(
|
||||
LetzshopHistoricalImportJob.vendor_id == vendor_id,
|
||||
)
|
||||
if status:
|
||||
hist_query = hist_query.filter(
|
||||
LetzshopHistoricalImportJob.status == status
|
||||
@@ -640,6 +648,7 @@ class LetzshopOrderService:
|
||||
).all()
|
||||
|
||||
for job in hist_jobs:
|
||||
v_name, v_code = vendor_lookup.get(job.vendor_id, (None, None))
|
||||
jobs.append(
|
||||
{
|
||||
"id": job.id,
|
||||
@@ -652,9 +661,9 @@ class LetzshopOrderService:
|
||||
"records_succeeded": (job.orders_imported or 0)
|
||||
+ (job.orders_updated or 0),
|
||||
"records_failed": job.orders_skipped or 0,
|
||||
"vendor_id": vendor_id,
|
||||
"vendor_name": vendor_name,
|
||||
"vendor_code": vendor_code,
|
||||
"vendor_id": job.vendor_id,
|
||||
"vendor_name": v_name,
|
||||
"vendor_code": v_code,
|
||||
"current_phase": job.current_phase,
|
||||
"error_message": job.error_message,
|
||||
}
|
||||
@@ -663,9 +672,12 @@ class LetzshopOrderService:
|
||||
# Product imports from marketplace_import_jobs
|
||||
if job_type in (None, "import"):
|
||||
import_query = self.db.query(MarketplaceImportJob).filter(
|
||||
MarketplaceImportJob.vendor_id == vendor_id,
|
||||
MarketplaceImportJob.marketplace == "Letzshop",
|
||||
)
|
||||
if vendor_id:
|
||||
import_query = import_query.filter(
|
||||
MarketplaceImportJob.vendor_id == vendor_id,
|
||||
)
|
||||
if status:
|
||||
import_query = import_query.filter(
|
||||
MarketplaceImportJob.status == status
|
||||
@@ -676,6 +688,7 @@ class LetzshopOrderService:
|
||||
).all()
|
||||
|
||||
for job in import_jobs:
|
||||
v_name, v_code = vendor_lookup.get(job.vendor_id, (None, None))
|
||||
jobs.append(
|
||||
{
|
||||
"id": job.id,
|
||||
@@ -688,24 +701,26 @@ class LetzshopOrderService:
|
||||
"records_succeeded": (job.imported_count or 0)
|
||||
+ (job.updated_count or 0),
|
||||
"records_failed": job.error_count or 0,
|
||||
"vendor_id": vendor_id,
|
||||
"vendor_name": vendor_name,
|
||||
"vendor_code": vendor_code,
|
||||
"vendor_id": job.vendor_id,
|
||||
"vendor_name": v_name,
|
||||
"vendor_code": v_code,
|
||||
}
|
||||
)
|
||||
|
||||
# Order syncs from letzshop_sync_logs
|
||||
if job_type in (None, "order_sync"):
|
||||
sync_query = self.db.query(LetzshopSyncLog).filter(
|
||||
LetzshopSyncLog.vendor_id == vendor_id,
|
||||
LetzshopSyncLog.operation_type == "order_import",
|
||||
)
|
||||
if vendor_id:
|
||||
sync_query = sync_query.filter(LetzshopSyncLog.vendor_id == vendor_id)
|
||||
if status:
|
||||
sync_query = sync_query.filter(LetzshopSyncLog.status == status)
|
||||
|
||||
sync_logs = sync_query.order_by(LetzshopSyncLog.created_at.desc()).all()
|
||||
|
||||
for log in sync_logs:
|
||||
v_name, v_code = vendor_lookup.get(log.vendor_id, (None, None))
|
||||
jobs.append(
|
||||
{
|
||||
"id": log.id,
|
||||
@@ -717,9 +732,9 @@ class LetzshopOrderService:
|
||||
"records_processed": log.records_processed or 0,
|
||||
"records_succeeded": log.records_succeeded or 0,
|
||||
"records_failed": log.records_failed or 0,
|
||||
"vendor_id": vendor_id,
|
||||
"vendor_name": vendor_name,
|
||||
"vendor_code": vendor_code,
|
||||
"vendor_id": log.vendor_id,
|
||||
"vendor_name": v_name,
|
||||
"vendor_code": v_code,
|
||||
"error_details": log.error_details,
|
||||
}
|
||||
)
|
||||
@@ -727,9 +742,10 @@ class LetzshopOrderService:
|
||||
# Product exports from letzshop_sync_logs
|
||||
if job_type in (None, "export"):
|
||||
export_query = self.db.query(LetzshopSyncLog).filter(
|
||||
LetzshopSyncLog.vendor_id == vendor_id,
|
||||
LetzshopSyncLog.operation_type == "product_export",
|
||||
)
|
||||
if vendor_id:
|
||||
export_query = export_query.filter(LetzshopSyncLog.vendor_id == vendor_id)
|
||||
if status:
|
||||
export_query = export_query.filter(LetzshopSyncLog.status == status)
|
||||
|
||||
@@ -738,6 +754,7 @@ class LetzshopOrderService:
|
||||
).all()
|
||||
|
||||
for log in export_logs:
|
||||
v_name, v_code = vendor_lookup.get(log.vendor_id, (None, None))
|
||||
jobs.append(
|
||||
{
|
||||
"id": log.id,
|
||||
@@ -749,10 +766,10 @@ class LetzshopOrderService:
|
||||
"records_processed": log.records_processed or 0,
|
||||
"records_succeeded": log.records_succeeded or 0,
|
||||
"records_failed": log.records_failed or 0,
|
||||
"vendor_id": vendor_id,
|
||||
"vendor_name": vendor_name,
|
||||
"vendor_code": vendor_code,
|
||||
"error_details": log.error_details, # Include export file details
|
||||
"vendor_id": log.vendor_id,
|
||||
"vendor_name": v_name,
|
||||
"vendor_code": v_code,
|
||||
"error_details": log.error_details,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user