code quality run

This commit is contained in:
2025-09-13 21:58:54 +02:00
parent 0dfd885847
commit 3eb18ef91e
63 changed files with 1802 additions and 1289 deletions

View File

@@ -1,10 +1,13 @@
import logging
from datetime import datetime
from typing import List, Optional
from sqlalchemy import func
from sqlalchemy.orm import Session
from models.api_models import (MarketplaceImportJobResponse,
MarketplaceImportRequest)
from models.database_models import MarketplaceImportJob, Shop, User
from models.api_models import MarketplaceImportRequest, MarketplaceImportJobResponse
from typing import Optional, List
from datetime import datetime
import logging
logger = logging.getLogger(__name__)
@@ -17,9 +20,11 @@ class MarketplaceService:
"""Validate that the shop exists and user has access to it"""
# Explicit type hint to help type checker shop: Optional[Shop]
# Use case-insensitive query to handle both uppercase and lowercase codes
shop: Optional[Shop] = db.query(Shop).filter(
func.upper(Shop.shop_code) == shop_code.upper()
).first()
shop: Optional[Shop] = (
db.query(Shop)
.filter(func.upper(Shop.shop_code) == shop_code.upper())
.first()
)
if not shop:
raise ValueError("Shop not found")
@@ -30,10 +35,7 @@ class MarketplaceService:
return shop
def create_import_job(
self,
db: Session,
request: MarketplaceImportRequest,
user: User
self, db: Session, request: MarketplaceImportRequest, user: User
) -> MarketplaceImportJob:
"""Create a new marketplace import job"""
# Validate shop access first
@@ -47,7 +49,7 @@ class MarketplaceService:
shop_id=shop.id, # Foreign key to shops table
shop_name=shop.shop_name, # Use shop.shop_name (the display name)
user_id=user.id,
created_at=datetime.utcnow()
created_at=datetime.utcnow(),
)
db.add(import_job)
@@ -55,13 +57,20 @@ class MarketplaceService:
db.refresh(import_job)
logger.info(
f"Created marketplace import job {import_job.id}: {request.marketplace} -> {shop.shop_name} (shop_code: {shop.shop_code}) by user {user.username}")
f"Created marketplace import job {import_job.id}: {request.marketplace} -> {shop.shop_name} (shop_code: {shop.shop_code}) by user {user.username}"
)
return import_job
def get_import_job_by_id(self, db: Session, job_id: int, user: User) -> MarketplaceImportJob:
def get_import_job_by_id(
self, db: Session, job_id: int, user: User
) -> MarketplaceImportJob:
"""Get a marketplace import job by ID with access control"""
job = db.query(MarketplaceImportJob).filter(MarketplaceImportJob.id == job_id).first()
job = (
db.query(MarketplaceImportJob)
.filter(MarketplaceImportJob.id == job_id)
.first()
)
if not job:
raise ValueError("Marketplace import job not found")
@@ -72,13 +81,13 @@ class MarketplaceService:
return job
def get_import_jobs(
self,
db: Session,
user: User,
marketplace: Optional[str] = None,
shop_name: Optional[str] = None,
skip: int = 0,
limit: int = 50
self,
db: Session,
user: User,
marketplace: Optional[str] = None,
shop_name: Optional[str] = None,
skip: int = 0,
limit: int = 50,
) -> List[MarketplaceImportJob]:
"""Get marketplace import jobs with filtering and access control"""
query = db.query(MarketplaceImportJob)
@@ -89,44 +98,51 @@ class MarketplaceService:
# Apply filters
if marketplace:
query = query.filter(MarketplaceImportJob.marketplace.ilike(f"%{marketplace}%"))
query = query.filter(
MarketplaceImportJob.marketplace.ilike(f"%{marketplace}%")
)
if shop_name:
query = query.filter(MarketplaceImportJob.shop_name.ilike(f"%{shop_name}%"))
# Order by creation date (newest first) and apply pagination
jobs = query.order_by(MarketplaceImportJob.created_at.desc()).offset(skip).limit(limit).all()
jobs = (
query.order_by(MarketplaceImportJob.created_at.desc())
.offset(skip)
.limit(limit)
.all()
)
return jobs
def update_job_status(
self,
db: Session,
job_id: int,
status: str,
**kwargs
self, db: Session, job_id: int, status: str, **kwargs
) -> MarketplaceImportJob:
"""Update marketplace import job status and other fields"""
job = db.query(MarketplaceImportJob).filter(MarketplaceImportJob.id == job_id).first()
job = (
db.query(MarketplaceImportJob)
.filter(MarketplaceImportJob.id == job_id)
.first()
)
if not job:
raise ValueError("Marketplace import job not found")
job.status = status
# Update optional fields if provided
if 'imported_count' in kwargs:
job.imported_count = kwargs['imported_count']
if 'updated_count' in kwargs:
job.updated_count = kwargs['updated_count']
if 'total_processed' in kwargs:
job.total_processed = kwargs['total_processed']
if 'error_count' in kwargs:
job.error_count = kwargs['error_count']
if 'error_message' in kwargs:
job.error_message = kwargs['error_message']
if 'started_at' in kwargs:
job.started_at = kwargs['started_at']
if 'completed_at' in kwargs:
job.completed_at = kwargs['completed_at']
if "imported_count" in kwargs:
job.imported_count = kwargs["imported_count"]
if "updated_count" in kwargs:
job.updated_count = kwargs["updated_count"]
if "total_processed" in kwargs:
job.total_processed = kwargs["total_processed"]
if "error_count" in kwargs:
job.error_count = kwargs["error_count"]
if "error_message" in kwargs:
job.error_message = kwargs["error_message"]
if "started_at" in kwargs:
job.started_at = kwargs["started_at"]
if "completed_at" in kwargs:
job.completed_at = kwargs["completed_at"]
db.commit()
db.refresh(job)
@@ -145,7 +161,9 @@ class MarketplaceService:
total_jobs = query.count()
pending_jobs = query.filter(MarketplaceImportJob.status == "pending").count()
running_jobs = query.filter(MarketplaceImportJob.status == "running").count()
completed_jobs = query.filter(MarketplaceImportJob.status == "completed").count()
completed_jobs = query.filter(
MarketplaceImportJob.status == "completed"
).count()
failed_jobs = query.filter(MarketplaceImportJob.status == "failed").count()
return {
@@ -153,17 +171,21 @@ class MarketplaceService:
"pending_jobs": pending_jobs,
"running_jobs": running_jobs,
"completed_jobs": completed_jobs,
"failed_jobs": failed_jobs
"failed_jobs": failed_jobs,
}
def convert_to_response_model(self, job: MarketplaceImportJob) -> MarketplaceImportJobResponse:
def convert_to_response_model(
self, job: MarketplaceImportJob
) -> MarketplaceImportJobResponse:
"""Convert database model to API response model"""
return MarketplaceImportJobResponse(
job_id=job.id,
status=job.status,
marketplace=job.marketplace,
shop_id=job.shop_id,
shop_code=job.shop.shop_code if job.shop else None, # Add this optional field via relationship
shop_code=(
job.shop.shop_code if job.shop else None
), # Add this optional field via relationship
shop_name=job.shop_name,
imported=job.imported_count or 0,
updated=job.updated_count or 0,
@@ -172,10 +194,12 @@ class MarketplaceService:
error_message=job.error_message,
created_at=job.created_at,
started_at=job.started_at,
completed_at=job.completed_at
completed_at=job.completed_at,
)
def cancel_import_job(self, db: Session, job_id: int, user: User) -> MarketplaceImportJob:
def cancel_import_job(
self, db: Session, job_id: int, user: User
) -> MarketplaceImportJob:
"""Cancel a pending or running import job"""
job = self.get_import_job_by_id(db, job_id, user)
@@ -197,7 +221,9 @@ class MarketplaceService:
# Only allow deletion of completed, failed, or cancelled jobs
if job.status in ["pending", "running"]:
raise ValueError(f"Cannot delete job with status: {job.status}. Cancel it first.")
raise ValueError(
f"Cannot delete job with status: {job.status}. Cancel it first."
)
db.delete(job)
db.commit()