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:
@@ -11,23 +11,20 @@ Handles:
|
||||
import logging
|
||||
import secrets
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, List, Dict, Any
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.permissions import get_preset_permissions
|
||||
from app.exceptions import (
|
||||
TeamMemberAlreadyExistsException,
|
||||
InvalidInvitationTokenException,
|
||||
TeamInvitationAlreadyAcceptedException,
|
||||
MaxTeamMembersReachedException,
|
||||
UserNotFoundException,
|
||||
VendorNotFoundException,
|
||||
CannotRemoveOwnerException,
|
||||
)
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor, VendorUser, VendorUserType, Role
|
||||
from app.exceptions import (CannotRemoveOwnerException,
|
||||
InvalidInvitationTokenException,
|
||||
MaxTeamMembersReachedException,
|
||||
TeamInvitationAlreadyAcceptedException,
|
||||
TeamMemberAlreadyExistsException,
|
||||
UserNotFoundException, VendorNotFoundException)
|
||||
from middleware.auth import AuthManager
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Role, Vendor, VendorUser, VendorUserType
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,13 +37,13 @@ class VendorTeamService:
|
||||
self.max_team_members = 50 # Configure as needed
|
||||
|
||||
def invite_team_member(
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
inviter: User,
|
||||
email: str,
|
||||
role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
inviter: User,
|
||||
email: str,
|
||||
role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Invite a new team member to a vendor.
|
||||
@@ -69,10 +66,14 @@ class VendorTeamService:
|
||||
"""
|
||||
try:
|
||||
# Check team size limit
|
||||
current_team_size = db.query(VendorUser).filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.is_active == True,
|
||||
).count()
|
||||
current_team_size = (
|
||||
db.query(VendorUser)
|
||||
.filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.is_active == True,
|
||||
)
|
||||
.count()
|
||||
)
|
||||
|
||||
if current_team_size >= self.max_team_members:
|
||||
raise MaxTeamMembersReachedException(
|
||||
@@ -85,22 +86,34 @@ class VendorTeamService:
|
||||
|
||||
if user:
|
||||
# Check if already a member
|
||||
existing_membership = db.query(VendorUser).filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user.id,
|
||||
).first()
|
||||
existing_membership = (
|
||||
db.query(VendorUser)
|
||||
.filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user.id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if existing_membership:
|
||||
if existing_membership.is_active:
|
||||
raise TeamMemberAlreadyExistsException(email, vendor.vendor_code)
|
||||
raise TeamMemberAlreadyExistsException(
|
||||
email, vendor.vendor_code
|
||||
)
|
||||
# Reactivate old membership
|
||||
existing_membership.is_active = False # Will be activated on acceptance
|
||||
existing_membership.invitation_token = self._generate_invitation_token()
|
||||
existing_membership.is_active = (
|
||||
False # Will be activated on acceptance
|
||||
)
|
||||
existing_membership.invitation_token = (
|
||||
self._generate_invitation_token()
|
||||
)
|
||||
existing_membership.invitation_sent_at = datetime.utcnow()
|
||||
existing_membership.invitation_accepted_at = None
|
||||
db.commit()
|
||||
|
||||
logger.info(f"Re-invited user {email} to vendor {vendor.vendor_code}")
|
||||
logger.info(
|
||||
f"Re-invited user {email} to vendor {vendor.vendor_code}"
|
||||
)
|
||||
return {
|
||||
"invitation_token": existing_membership.invitation_token,
|
||||
"email": email,
|
||||
@@ -108,7 +121,7 @@ class VendorTeamService:
|
||||
}
|
||||
else:
|
||||
# Create new user account (inactive until invitation accepted)
|
||||
username = email.split('@')[0]
|
||||
username = email.split("@")[0]
|
||||
# Ensure unique username
|
||||
base_username = username
|
||||
counter = 1
|
||||
@@ -179,12 +192,12 @@ class VendorTeamService:
|
||||
raise
|
||||
|
||||
def accept_invitation(
|
||||
self,
|
||||
db: Session,
|
||||
invitation_token: str,
|
||||
password: str,
|
||||
first_name: Optional[str] = None,
|
||||
last_name: Optional[str] = None,
|
||||
self,
|
||||
db: Session,
|
||||
invitation_token: str,
|
||||
password: str,
|
||||
first_name: Optional[str] = None,
|
||||
last_name: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Accept a team invitation and activate account.
|
||||
@@ -201,9 +214,13 @@ class VendorTeamService:
|
||||
"""
|
||||
try:
|
||||
# Find invitation
|
||||
vendor_user = db.query(VendorUser).filter(
|
||||
VendorUser.invitation_token == invitation_token,
|
||||
).first()
|
||||
vendor_user = (
|
||||
db.query(VendorUser)
|
||||
.filter(
|
||||
VendorUser.invitation_token == invitation_token,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not vendor_user:
|
||||
raise InvalidInvitationTokenException()
|
||||
@@ -247,7 +264,10 @@ class VendorTeamService:
|
||||
"role": vendor_user.role.name if vendor_user.role else "member",
|
||||
}
|
||||
|
||||
except (InvalidInvitationTokenException, TeamInvitationAlreadyAcceptedException):
|
||||
except (
|
||||
InvalidInvitationTokenException,
|
||||
TeamInvitationAlreadyAcceptedException,
|
||||
):
|
||||
raise
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
@@ -255,10 +275,10 @@ class VendorTeamService:
|
||||
raise
|
||||
|
||||
def remove_team_member(
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
user_id: int,
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
user_id: int,
|
||||
) -> bool:
|
||||
"""
|
||||
Remove a team member from a vendor.
|
||||
@@ -274,10 +294,14 @@ class VendorTeamService:
|
||||
True if removed
|
||||
"""
|
||||
try:
|
||||
vendor_user = db.query(VendorUser).filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user_id,
|
||||
).first()
|
||||
vendor_user = (
|
||||
db.query(VendorUser)
|
||||
.filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not vendor_user:
|
||||
raise UserNotFoundException(str(user_id))
|
||||
@@ -301,12 +325,12 @@ class VendorTeamService:
|
||||
raise
|
||||
|
||||
def update_member_role(
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
user_id: int,
|
||||
new_role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
user_id: int,
|
||||
new_role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
) -> VendorUser:
|
||||
"""
|
||||
Update a team member's role.
|
||||
@@ -322,10 +346,14 @@ class VendorTeamService:
|
||||
Updated VendorUser
|
||||
"""
|
||||
try:
|
||||
vendor_user = db.query(VendorUser).filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user_id,
|
||||
).first()
|
||||
vendor_user = (
|
||||
db.query(VendorUser)
|
||||
.filter(
|
||||
VendorUser.vendor_id == vendor.id,
|
||||
VendorUser.user_id == user_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not vendor_user:
|
||||
raise UserNotFoundException(str(user_id))
|
||||
@@ -360,10 +388,10 @@ class VendorTeamService:
|
||||
raise
|
||||
|
||||
def get_team_members(
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
include_inactive: bool = False,
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
include_inactive: bool = False,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Get all team members for a vendor.
|
||||
@@ -387,20 +415,22 @@ class VendorTeamService:
|
||||
|
||||
members = []
|
||||
for vu in vendor_users:
|
||||
members.append({
|
||||
"id": vu.user.id,
|
||||
"email": vu.user.email,
|
||||
"username": vu.user.username,
|
||||
"full_name": vu.user.full_name,
|
||||
"user_type": vu.user_type,
|
||||
"role": vu.role.name if vu.role else "owner",
|
||||
"permissions": vu.get_all_permissions(),
|
||||
"is_active": vu.is_active,
|
||||
"is_owner": vu.is_owner,
|
||||
"invitation_pending": vu.is_invitation_pending,
|
||||
"invited_at": vu.invitation_sent_at,
|
||||
"accepted_at": vu.invitation_accepted_at,
|
||||
})
|
||||
members.append(
|
||||
{
|
||||
"id": vu.user.id,
|
||||
"email": vu.user.email,
|
||||
"username": vu.user.username,
|
||||
"full_name": vu.user.full_name,
|
||||
"user_type": vu.user_type,
|
||||
"role": vu.role.name if vu.role else "owner",
|
||||
"permissions": vu.get_all_permissions(),
|
||||
"is_active": vu.is_active,
|
||||
"is_owner": vu.is_owner,
|
||||
"invitation_pending": vu.is_invitation_pending,
|
||||
"invited_at": vu.invitation_sent_at,
|
||||
"accepted_at": vu.invitation_accepted_at,
|
||||
}
|
||||
)
|
||||
|
||||
return members
|
||||
|
||||
@@ -411,18 +441,22 @@ class VendorTeamService:
|
||||
return secrets.token_urlsafe(32)
|
||||
|
||||
def _get_or_create_role(
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
self,
|
||||
db: Session,
|
||||
vendor: Vendor,
|
||||
role_name: str,
|
||||
custom_permissions: Optional[List[str]] = None,
|
||||
) -> Role:
|
||||
"""Get existing role or create new one with preset/custom permissions."""
|
||||
# Try to find existing role with same name
|
||||
role = db.query(Role).filter(
|
||||
Role.vendor_id == vendor.id,
|
||||
Role.name == role_name,
|
||||
).first()
|
||||
role = (
|
||||
db.query(Role)
|
||||
.filter(
|
||||
Role.vendor_id == vendor.id,
|
||||
Role.name == role_name,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
if role and custom_permissions is None:
|
||||
# Use existing role
|
||||
|
||||
Reference in New Issue
Block a user