# Removed __future__ annotations to fix OpenAPI schema generation from fastapi import APIRouter, Depends, Request, HTTPException from sqlalchemy.orm import Session from adapters.db.session import get_db from adapters.api.v1.schemas import ( BusinessUsersListResponse, AddUserRequest, AddUserResponse, UpdatePermissionsRequest, UpdatePermissionsResponse, RemoveUserResponse ) from app.core.responses import success_response, format_datetime_fields from app.core.auth_dependency import get_current_user, AuthContext from app.core.permissions import require_business_access from adapters.db.repositories.business_permission_repo import BusinessPermissionRepository from adapters.db.models.user import User from adapters.db.models.business import Business router = APIRouter(prefix="/business", tags=["business-users"]) @router.get("/{business_id}/users", summary="لیست کاربران کسب و کار", description="دریافت لیست کاربران یک کسب و کار", response_model=BusinessUsersListResponse, responses={ 200: { "description": "لیست کاربران با موفقیت دریافت شد", "content": { "application/json": { "example": { "success": True, "message": "لیست کاربران دریافت شد", "users": [ { "id": 1, "business_id": 1, "user_id": 2, "user_name": "علی احمدی", "user_email": "ali@example.com", "user_phone": "09123456789", "role": "member", "status": "active", "added_at": "2024-01-01T00:00:00Z", "last_active": "2024-01-01T12:00:00Z", "permissions": { "sales": { "read": True, "write": True, "delete": False }, "reports": { "read": True, "export": True } } } ], "total_count": 1 } } } }, 401: { "description": "کاربر احراز هویت نشده است" }, 403: { "description": "دسترسی غیرمجاز به کسب و کار" } } ) @require_business_access("business_id") def get_users( request: Request, business_id: int, ctx: AuthContext = Depends(get_current_user), db: Session = Depends(get_db) ) -> dict: """دریافت لیست کاربران کسب و کار""" import logging logger = logging.getLogger(__name__) current_user_id = ctx.get_user_id() logger.info(f"Getting users for business {business_id}, current user: {current_user_id}") # Check if user is business owner or has permission to manage users business = db.get(Business, business_id) if not business: logger.error(f"Business {business_id} not found") raise HTTPException(status_code=404, detail="کسب و کار یافت نشد") is_owner = business.owner_id == current_user_id can_manage = ctx.can_manage_business_users() logger.info(f"Business owner: {business.owner_id}, is_owner: {is_owner}, can_manage: {can_manage}") if not is_owner and not can_manage: logger.warning(f"User {current_user_id} does not have permission to manage users for business {business_id}") raise HTTPException(status_code=403, detail="شما مجوز مدیریت کاربران ندارید") # Get business permissions for this business permission_repo = BusinessPermissionRepository(db) business_permissions = permission_repo.get_business_users(business_id) logger.info(f"Found {len(business_permissions)} business permissions for business {business_id}") # Format users data formatted_users = [] # Add business owner first owner = db.get(User, business.owner_id) if owner: logger.info(f"Adding business owner: {owner.id} - {owner.email}") owner_data = { "id": business.owner_id, # Use owner_id as id "business_id": business_id, "user_id": business.owner_id, "user_name": f"{owner.first_name or ''} {owner.last_name or ''}".strip(), "user_email": owner.email or "", "user_phone": owner.mobile, "role": "owner", "status": "active", "added_at": business.created_at, "last_active": business.updated_at, "permissions": {}, # Owner has all permissions } formatted_users.append(owner_data) else: logger.warning(f"Business owner {business.owner_id} not found in users table") # Add other users with permissions for perm in business_permissions: # Skip if this is the owner (already added) if perm.user_id == business.owner_id: logger.info(f"Skipping owner user {perm.user_id} as already added") continue user = db.get(User, perm.user_id) if user: logger.info(f"Adding user with permissions: {user.id} - {user.email}") user_data = { "id": perm.id, "business_id": perm.business_id, "user_id": perm.user_id, "user_name": f"{user.first_name or ''} {user.last_name or ''}".strip(), "user_email": user.email or "", "user_phone": user.mobile, "role": "member", "status": "active", "added_at": perm.created_at, "last_active": perm.updated_at, "permissions": perm.business_permissions or {}, } formatted_users.append(user_data) else: logger.warning(f"User {perm.user_id} not found in users table") logger.info(f"Returning {len(formatted_users)} users for business {business_id}") # Format datetime fields based on calendar type formatted_users = format_datetime_fields(formatted_users, request) return success_response( data={ "users": formatted_users, "total_count": len(formatted_users) }, request=request, message="لیست کاربران دریافت شد" ) @router.post("/{business_id}/users", summary="افزودن کاربر به کسب و کار", description="افزودن کاربر جدید به کسب و کار با ایمیل یا شماره تلفن", response_model=AddUserResponse, responses={ 200: { "description": "کاربر با موفقیت اضافه شد", "content": { "application/json": { "example": { "success": True, "message": "کاربر با موفقیت اضافه شد", "user": { "id": 1, "business_id": 1, "user_id": 2, "user_name": "علی احمدی", "user_email": "ali@example.com", "user_phone": "09123456789", "role": "member", "status": "active", "added_at": "2024-01-01T00:00:00Z", "last_active": None, "permissions": {} } } } } }, 400: { "description": "خطا در اعتبارسنجی داده‌ها" }, 401: { "description": "کاربر احراز هویت نشده است" }, 403: { "description": "دسترسی غیرمجاز یا مجوز کافی نیست" }, 404: { "description": "کاربر یافت نشد" } } ) @require_business_access("business_id") def add_user( request: Request, business_id: int, add_request: AddUserRequest, ctx: AuthContext = Depends(get_current_user), db: Session = Depends(get_db) ) -> dict: """افزودن کاربر به کسب و کار""" import logging logger = logging.getLogger(__name__) current_user_id = ctx.get_user_id() logger.info(f"Adding user to business {business_id}, current user: {current_user_id}") logger.info(f"Add request: {add_request.email_or_phone}") # Check if user is business owner or has permission to manage users business = db.get(Business, business_id) if not business: logger.error(f"Business {business_id} not found") raise HTTPException(status_code=404, detail="کسب و کار یافت نشد") is_owner = business.owner_id == current_user_id can_manage = ctx.can_manage_business_users(business_id) logger.info(f"Business owner: {business.owner_id}, is_owner: {is_owner}, can_manage: {can_manage}") logger.info(f"User {current_user_id} business_id from context: {ctx.business_id}") logger.info(f"User {current_user_id} is superadmin: {ctx.is_superadmin()}") if not is_owner and not can_manage: logger.warning(f"User {current_user_id} does not have permission to add users to business {business_id}") raise HTTPException(status_code=403, detail="شما مجوز مدیریت کاربران ندارید") # Find user by email or phone logger.info(f"Searching for user with email/phone: {add_request.email_or_phone}") user = db.query(User).filter( (User.email == add_request.email_or_phone) | (User.mobile == add_request.email_or_phone) ).first() if not user: logger.warning(f"User not found with email/phone: {add_request.email_or_phone}") raise HTTPException(status_code=404, detail="کاربر یافت نشد") logger.info(f"Found user: {user.id} - {user.email}") # Check if user is already added to this business permission_repo = BusinessPermissionRepository(db) existing_permission = permission_repo.get_by_user_and_business(user.id, business_id) if existing_permission: logger.warning(f"User {user.id} already exists in business {business_id}") raise HTTPException(status_code=400, detail="کاربر قبلاً به این کسب و کار اضافه شده است") # Add user to business with default permissions logger.info(f"Adding user {user.id} to business {business_id}") permission_obj = permission_repo.create_or_update( user_id=user.id, business_id=business_id, permissions={} # Default empty permissions ) logger.info(f"Created permission object: {permission_obj.id}") # Format user data user_data = { "id": permission_obj.id, "business_id": permission_obj.business_id, "user_id": permission_obj.user_id, "user_name": f"{user.first_name or ''} {user.last_name or ''}".strip(), "user_email": user.email or "", "user_phone": user.mobile, "role": "member", "status": "active", "added_at": permission_obj.created_at, "last_active": None, "permissions": permission_obj.business_permissions or {}, } logger.info(f"Returning user data: {user_data}") # Format datetime fields based on calendar type formatted_user_data = format_datetime_fields(user_data, request) return success_response( data={"user": formatted_user_data}, request=request, message="کاربر با موفقیت اضافه شد" ) @router.put("/{business_id}/users/{user_id}/permissions", summary="به‌روزرسانی دسترسی‌های کاربر", description="به‌روزرسانی دسترسی‌های یک کاربر در کسب و کار", response_model=UpdatePermissionsResponse, responses={ 200: { "description": "دسترسی‌ها با موفقیت به‌روزرسانی شد", "content": { "application/json": { "example": { "success": True, "message": "دسترسی‌ها با موفقیت به‌روزرسانی شد" } } } }, 400: { "description": "خطا در اعتبارسنجی داده‌ها" }, 401: { "description": "کاربر احراز هویت نشده است" }, 403: { "description": "دسترسی غیرمجاز یا مجوز کافی نیست" }, 404: { "description": "کاربر یافت نشد" } } ) @require_business_access("business_id") def update_permissions( request: Request, business_id: int, user_id: int, update_request: UpdatePermissionsRequest, ctx: AuthContext = Depends(get_current_user), db: Session = Depends(get_db) ) -> dict: """به‌روزرسانی دسترسی‌های کاربر""" current_user_id = ctx.get_user_id() # Check if user is business owner or has permission to manage users business = db.get(Business, business_id) if not business: raise HTTPException(status_code=404, detail="کسب و کار یافت نشد") is_owner = business.owner_id == current_user_id can_manage = ctx.can_manage_business_users() if not is_owner and not can_manage: raise HTTPException(status_code=403, detail="شما مجوز مدیریت کاربران ندارید") # Check if target user exists target_user = db.get(User, user_id) if not target_user: raise HTTPException(status_code=404, detail="کاربر یافت نشد") # Update permissions permission_repo = BusinessPermissionRepository(db) permission_obj = permission_repo.create_or_update( user_id=user_id, business_id=business_id, permissions=update_request.permissions ) return success_response( data={}, request=request, message="دسترسی‌ها با موفقیت به‌روزرسانی شد" ) @router.delete("/{business_id}/users/{user_id}", summary="حذف کاربر از کسب و کار", description="حذف کاربر از کسب و کار", response_model=RemoveUserResponse, responses={ 200: { "description": "کاربر با موفقیت حذف شد", "content": { "application/json": { "example": { "success": True, "message": "کاربر با موفقیت حذف شد" } } } }, 401: { "description": "کاربر احراز هویت نشده است" }, 403: { "description": "دسترسی غیرمجاز یا مجوز کافی نیست" }, 404: { "description": "کاربر یافت نشد" } } ) @require_business_access("business_id") def remove_user( request: Request, business_id: int, user_id: int, ctx: AuthContext = Depends(get_current_user), db: Session = Depends(get_db) ) -> dict: """حذف کاربر از کسب و کار""" current_user_id = ctx.get_user_id() # Check if user is business owner or has permission to manage users business = db.get(Business, business_id) if not business: raise HTTPException(status_code=404, detail="کسب و کار یافت نشد") is_owner = business.owner_id == current_user_id can_manage = ctx.can_manage_business_users() if not is_owner and not can_manage: raise HTTPException(status_code=403, detail="شما مجوز مدیریت کاربران ندارید") # Check if target user is business owner business = db.get(Business, business_id) if business and business.owner_id == user_id: raise HTTPException(status_code=400, detail="نمی‌توان مالک کسب و کار را حذف کرد") # Remove user permissions permission_repo = BusinessPermissionRepository(db) success = permission_repo.delete_by_user_and_business(user_id, business_id) if not success: raise HTTPException(status_code=404, detail="کاربر یافت نشد") return success_response( data={}, request=request, message="کاربر با موفقیت حذف شد" )