style: apply black and isort formatting across entire codebase

- Standardize quote style (single to double quotes)
- Reorder and group imports alphabetically
- Fix line breaks and indentation for consistency
- Apply PEP 8 formatting standards

Also updated Makefile to exclude both venv and .venv from code quality checks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-28 19:30:17 +01:00
parent 13f0094743
commit 21c13ca39b
236 changed files with 8450 additions and 6545 deletions

View File

@@ -16,24 +16,19 @@ import string
from datetime import datetime, timezone
from typing import List, Optional, Tuple
from sqlalchemy.orm import Session
from sqlalchemy import func, or_
from sqlalchemy.orm import Session
from app.exceptions import (
UserNotFoundException,
UserStatusChangeException,
CannotModifySelfException,
VendorNotFoundException,
VendorAlreadyExistsException,
VendorVerificationException,
AdminOperationException,
ValidationException,
)
from app.exceptions import (AdminOperationException, CannotModifySelfException,
UserNotFoundException, UserStatusChangeException,
ValidationException, VendorAlreadyExistsException,
VendorNotFoundException,
VendorVerificationException)
from models.database.marketplace_import_job import MarketplaceImportJob
from models.database.user import User
from models.database.vendor import Role, Vendor, VendorUser
from models.schema.marketplace_import_job import MarketplaceImportJobResponse
from models.schema.vendor import VendorCreate
from models.database.marketplace_import_job import MarketplaceImportJob
from models.database.vendor import Vendor, Role, VendorUser
from models.database.user import User
logger = logging.getLogger(__name__)
@@ -52,12 +47,11 @@ class AdminService:
except Exception as e:
logger.error(f"Failed to retrieve users: {str(e)}")
raise AdminOperationException(
operation="get_all_users",
reason="Database query failed"
operation="get_all_users", reason="Database query failed"
)
def toggle_user_status(
self, db: Session, user_id: int, current_admin_id: int
self, db: Session, user_id: int, current_admin_id: int
) -> Tuple[User, str]:
"""Toggle user active status."""
user = self._get_user_by_id_or_raise(db, user_id)
@@ -72,7 +66,7 @@ class AdminService:
user_id=user_id,
current_status="admin",
attempted_action="toggle status",
reason="Cannot modify another admin user"
reason="Cannot modify another admin user",
)
try:
@@ -95,7 +89,7 @@ class AdminService:
user_id=user_id,
current_status="active" if original_status else "inactive",
attempted_action="toggle status",
reason="Database update failed"
reason="Database update failed",
)
# ============================================================================
@@ -103,7 +97,7 @@ class AdminService:
# ============================================================================
def create_vendor_with_owner(
self, db: Session, vendor_data: VendorCreate
self, db: Session, vendor_data: VendorCreate
) -> Tuple[Vendor, User, str]:
"""
Create vendor with owner user account.
@@ -118,17 +112,23 @@ class AdminService:
"""
try:
# Check if vendor code already exists
existing_vendor = db.query(Vendor).filter(
func.upper(Vendor.vendor_code) == vendor_data.vendor_code.upper()
).first()
existing_vendor = (
db.query(Vendor)
.filter(
func.upper(Vendor.vendor_code) == vendor_data.vendor_code.upper()
)
.first()
)
if existing_vendor:
raise VendorAlreadyExistsException(vendor_data.vendor_code)
# Check if subdomain already exists
existing_subdomain = db.query(Vendor).filter(
func.lower(Vendor.subdomain) == vendor_data.subdomain.lower()
).first()
existing_subdomain = (
db.query(Vendor)
.filter(func.lower(Vendor.subdomain) == vendor_data.subdomain.lower())
.first()
)
if existing_subdomain:
raise ValidationException(
@@ -140,15 +140,14 @@ class AdminService:
# Create owner user with owner_email
from middleware.auth import AuthManager
auth_manager = AuthManager()
owner_username = f"{vendor_data.subdomain}_owner"
owner_email = vendor_data.owner_email # ✅ For User authentication
# Check if user with this email already exists
existing_user = db.query(User).filter(
User.email == owner_email
).first()
existing_user = db.query(User).filter(User.email == owner_email).first()
if existing_user:
# Use existing user as owner
@@ -215,17 +214,17 @@ class AdminService:
logger.error(f"Failed to create vendor: {str(e)}")
raise AdminOperationException(
operation="create_vendor_with_owner",
reason=f"Failed to create vendor: {str(e)}"
reason=f"Failed to create vendor: {str(e)}",
)
def get_all_vendors(
self,
db: Session,
skip: int = 0,
limit: int = 100,
search: Optional[str] = None,
is_active: Optional[bool] = None,
is_verified: Optional[bool] = None
self,
db: Session,
skip: int = 0,
limit: int = 100,
search: Optional[str] = None,
is_active: Optional[bool] = None,
is_verified: Optional[bool] = None,
) -> Tuple[List[Vendor], int]:
"""Get paginated list of all vendors with filtering."""
try:
@@ -238,7 +237,7 @@ class AdminService:
or_(
Vendor.name.ilike(search_term),
Vendor.vendor_code.ilike(search_term),
Vendor.subdomain.ilike(search_term)
Vendor.subdomain.ilike(search_term),
)
)
@@ -255,8 +254,7 @@ class AdminService:
except Exception as e:
logger.error(f"Failed to retrieve vendors: {str(e)}")
raise AdminOperationException(
operation="get_all_vendors",
reason="Database query failed"
operation="get_all_vendors", reason="Database query failed"
)
def get_vendor_by_id(self, db: Session, vendor_id: int) -> Vendor:
@@ -290,7 +288,7 @@ class AdminService:
raise VendorVerificationException(
vendor_id=vendor_id,
reason="Database update failed",
current_verification_status=original_status
current_verification_status=original_status,
)
def toggle_vendor_status(self, db: Session, vendor_id: int) -> Tuple[Vendor, str]:
@@ -317,7 +315,7 @@ class AdminService:
operation="toggle_vendor_status",
reason="Database update failed",
target_type="vendor",
target_id=str(vendor_id)
target_id=str(vendor_id),
)
def delete_vendor(self, db: Session, vendor_id: int) -> str:
@@ -345,15 +343,11 @@ class AdminService:
db.rollback()
logger.error(f"Failed to delete vendor {vendor_id}: {str(e)}")
raise AdminOperationException(
operation="delete_vendor",
reason="Database deletion failed"
operation="delete_vendor", reason="Database deletion failed"
)
def update_vendor(
self,
db: Session,
vendor_id: int,
vendor_update # VendorUpdate schema
self, db: Session, vendor_id: int, vendor_update # VendorUpdate schema
) -> Vendor:
"""
Update vendor information (Admin only).
@@ -387,11 +381,18 @@ class AdminService:
update_data = vendor_update.model_dump(exclude_unset=True)
# Check subdomain uniqueness if changing
if 'subdomain' in update_data and update_data['subdomain'] != vendor.subdomain:
existing = db.query(Vendor).filter(
Vendor.subdomain == update_data['subdomain'],
Vendor.id != vendor_id
).first()
if (
"subdomain" in update_data
and update_data["subdomain"] != vendor.subdomain
):
existing = (
db.query(Vendor)
.filter(
Vendor.subdomain == update_data["subdomain"],
Vendor.id != vendor_id,
)
.first()
)
if existing:
raise ValidationException(
f"Subdomain '{update_data['subdomain']}' is already taken"
@@ -419,17 +420,16 @@ class AdminService:
db.rollback()
logger.error(f"Failed to update vendor {vendor_id}: {str(e)}")
raise AdminOperationException(
operation="update_vendor",
reason=f"Database update failed: {str(e)}"
operation="update_vendor", reason=f"Database update failed: {str(e)}"
)
# Add this NEW method for transferring ownership:
def transfer_vendor_ownership(
self,
db: Session,
vendor_id: int,
transfer_data # VendorTransferOwnership schema
self,
db: Session,
vendor_id: int,
transfer_data, # VendorTransferOwnership schema
) -> Tuple[Vendor, User, User]:
"""
Transfer vendor ownership to another user.
@@ -466,9 +466,9 @@ class AdminService:
old_owner = vendor.owner
# Get new owner
new_owner = db.query(User).filter(
User.id == transfer_data.new_owner_user_id
).first()
new_owner = (
db.query(User).filter(User.id == transfer_data.new_owner_user_id).first()
)
if not new_owner:
raise UserNotFoundException(str(transfer_data.new_owner_user_id))
@@ -487,26 +487,32 @@ class AdminService:
try:
# Get Owner role for this vendor
owner_role = db.query(Role).filter(
Role.vendor_id == vendor_id,
Role.name == "Owner"
).first()
owner_role = (
db.query(Role)
.filter(Role.vendor_id == vendor_id, Role.name == "Owner")
.first()
)
if not owner_role:
raise ValidationException("Owner role not found for vendor")
# Get Manager role (to demote old owner)
manager_role = db.query(Role).filter(
Role.vendor_id == vendor_id,
Role.name == "Manager"
).first()
manager_role = (
db.query(Role)
.filter(Role.vendor_id == vendor_id, Role.name == "Manager")
.first()
)
# Remove old owner from Owner role
old_owner_link = db.query(VendorUser).filter(
VendorUser.vendor_id == vendor_id,
VendorUser.user_id == old_owner.id,
VendorUser.role_id == owner_role.id
).first()
old_owner_link = (
db.query(VendorUser)
.filter(
VendorUser.vendor_id == vendor_id,
VendorUser.user_id == old_owner.id,
VendorUser.role_id == owner_role.id,
)
.first()
)
if old_owner_link:
if manager_role:
@@ -525,10 +531,14 @@ class AdminService:
)
# Check if new owner already has a vendor_user link
new_owner_link = db.query(VendorUser).filter(
VendorUser.vendor_id == vendor_id,
VendorUser.user_id == new_owner.id
).first()
new_owner_link = (
db.query(VendorUser)
.filter(
VendorUser.vendor_id == vendor_id,
VendorUser.user_id == new_owner.id,
)
.first()
)
if new_owner_link:
# Update existing link to Owner role
@@ -540,7 +550,7 @@ class AdminService:
vendor_id=vendor_id,
user_id=new_owner.id,
role_id=owner_role.id,
is_active=True
is_active=True,
)
db.add(new_owner_link)
@@ -568,10 +578,12 @@ class AdminService:
raise
except Exception as e:
db.rollback()
logger.error(f"Failed to transfer ownership for vendor {vendor_id}: {str(e)}")
logger.error(
f"Failed to transfer ownership for vendor {vendor_id}: {str(e)}"
)
raise AdminOperationException(
operation="transfer_vendor_ownership",
reason=f"Ownership transfer failed: {str(e)}"
reason=f"Ownership transfer failed: {str(e)}",
)
# ============================================================================
@@ -579,13 +591,13 @@ class AdminService:
# ============================================================================
def get_marketplace_import_jobs(
self,
db: Session,
marketplace: Optional[str] = None,
vendor_name: Optional[str] = None,
status: Optional[str] = None,
skip: int = 0,
limit: int = 100,
self,
db: Session,
marketplace: Optional[str] = None,
vendor_name: Optional[str] = None,
status: Optional[str] = None,
skip: int = 0,
limit: int = 100,
) -> List[MarketplaceImportJobResponse]:
"""Get filtered and paginated marketplace import jobs."""
try:
@@ -596,7 +608,9 @@ class AdminService:
MarketplaceImportJob.marketplace.ilike(f"%{marketplace}%")
)
if vendor_name:
query = query.filter(MarketplaceImportJob.vendor_name.ilike(f"%{vendor_name}%"))
query = query.filter(
MarketplaceImportJob.vendor_name.ilike(f"%{vendor_name}%")
)
if status:
query = query.filter(MarketplaceImportJob.status == status)
@@ -612,8 +626,7 @@ class AdminService:
except Exception as e:
logger.error(f"Failed to retrieve marketplace import jobs: {str(e)}")
raise AdminOperationException(
operation="get_marketplace_import_jobs",
reason="Database query failed"
operation="get_marketplace_import_jobs", reason="Database query failed"
)
# ============================================================================
@@ -624,10 +637,7 @@ class AdminService:
"""Get recently created vendors."""
try:
vendors = (
db.query(Vendor)
.order_by(Vendor.created_at.desc())
.limit(limit)
.all()
db.query(Vendor).order_by(Vendor.created_at.desc()).limit(limit).all()
)
return [
@@ -638,7 +648,7 @@ class AdminService:
"subdomain": v.subdomain,
"is_active": v.is_active,
"is_verified": v.is_verified,
"created_at": v.created_at
"created_at": v.created_at,
}
for v in vendors
]
@@ -663,7 +673,7 @@ class AdminService:
"vendor_name": j.vendor_name,
"status": j.status,
"total_processed": j.total_processed or 0,
"created_at": j.created_at
"created_at": j.created_at,
}
for j in jobs
]
@@ -692,47 +702,53 @@ class AdminService:
def _generate_temp_password(self, length: int = 12) -> str:
"""Generate secure temporary password."""
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
return ''.join(secrets.choice(alphabet) for _ in range(length))
return "".join(secrets.choice(alphabet) for _ in range(length))
def _create_default_roles(self, db: Session, vendor_id: int):
"""Create default roles for a new vendor."""
default_roles = [
{
"name": "Owner",
"permissions": ["*"] # Full access
},
{"name": "Owner", "permissions": ["*"]}, # Full access
{
"name": "Manager",
"permissions": [
"products.*", "orders.*", "customers.view",
"inventory.*", "team.view"
]
"products.*",
"orders.*",
"customers.view",
"inventory.*",
"team.view",
],
},
{
"name": "Editor",
"permissions": [
"products.view", "products.edit",
"orders.view", "inventory.view"
]
"products.view",
"products.edit",
"orders.view",
"inventory.view",
],
},
{
"name": "Viewer",
"permissions": [
"products.view", "orders.view",
"customers.view", "inventory.view"
]
}
"products.view",
"orders.view",
"customers.view",
"inventory.view",
],
},
]
for role_data in default_roles:
role = Role(
vendor_id=vendor_id,
name=role_data["name"],
permissions=role_data["permissions"]
permissions=role_data["permissions"],
)
db.add(role)
def _convert_job_to_response(self, job: MarketplaceImportJob) -> MarketplaceImportJobResponse:
def _convert_job_to_response(
self, job: MarketplaceImportJob
) -> MarketplaceImportJobResponse:
"""Convert database model to response schema."""
return MarketplaceImportJobResponse(
job_id=job.id,