# app/exceptions/vendor.py """ Vendor management specific exceptions. """ from typing import Any from .base import ( AuthorizationException, BusinessLogicException, ConflictException, ResourceNotFoundException, ValidationException, ) class VendorNotFoundException(ResourceNotFoundException): """Raised when a vendor is not found.""" def __init__(self, vendor_identifier: str, identifier_type: str = "code"): if identifier_type.lower() == "id": message = f"Vendor with ID '{vendor_identifier}' not found" else: message = f"Vendor with code '{vendor_identifier}' not found" super().__init__( resource_type="Vendor", identifier=vendor_identifier, message=message, error_code="VENDOR_NOT_FOUND", ) class VendorAlreadyExistsException(ConflictException): """Raised when trying to create a vendor that already exists.""" def __init__(self, vendor_code: str): super().__init__( message=f"Vendor with code '{vendor_code}' already exists", error_code="VENDOR_ALREADY_EXISTS", details={"vendor_code": vendor_code}, ) class VendorNotActiveException(BusinessLogicException): """Raised when trying to perform operations on inactive vendor.""" def __init__(self, vendor_code: str): super().__init__( message=f"Vendor '{vendor_code}' is not active", error_code="VENDOR_NOT_ACTIVE", details={"vendor_code": vendor_code}, ) class VendorNotVerifiedException(BusinessLogicException): """Raised when trying to perform operations requiring verified vendor.""" def __init__(self, vendor_code: str): super().__init__( message=f"Vendor '{vendor_code}' is not verified", error_code="VENDOR_NOT_VERIFIED", details={"vendor_code": vendor_code}, ) class UnauthorizedVendorAccessException(AuthorizationException): """Raised when user tries to access vendor they don't own.""" def __init__(self, vendor_code: str, user_id: int | None = None): details = {"vendor_code": vendor_code} if user_id: details["user_id"] = user_id super().__init__( message=f"Unauthorized access to vendor '{vendor_code}'", error_code="UNAUTHORIZED_VENDOR_ACCESS", details=details, ) class InvalidVendorDataException(ValidationException): """Raised when vendor data is invalid or incomplete.""" def __init__( self, message: str = "Invalid vendor data", field: str | None = None, details: dict[str, Any] | None = None, ): super().__init__( message=message, field=field, details=details, ) self.error_code = "INVALID_VENDOR_DATA" class VendorValidationException(ValidationException): """Raised when vendor validation fails.""" def __init__( self, message: str = "Vendor validation failed", field: str | None = None, validation_errors: dict[str, str] | None = None, ): details = {} if validation_errors: details["validation_errors"] = validation_errors super().__init__( message=message, field=field, details=details, ) self.error_code = "VENDOR_VALIDATION_FAILED" class IncompleteVendorDataException(ValidationException): """Raised when vendor data is missing required fields.""" def __init__( self, vendor_code: str, missing_fields: list, ): super().__init__( message=f"Vendor '{vendor_code}' is missing required fields: {', '.join(missing_fields)}", details={ "vendor_code": vendor_code, "missing_fields": missing_fields, }, ) self.error_code = "INCOMPLETE_VENDOR_DATA" class MaxVendorsReachedException(BusinessLogicException): """Raised when user tries to create more vendors than allowed.""" def __init__(self, max_vendors: int, user_id: int | None = None): details = {"max_vendors": max_vendors} if user_id: details["user_id"] = user_id super().__init__( message=f"Maximum number of vendors reached ({max_vendors})", error_code="MAX_VENDORS_REACHED", details=details, ) class VendorAccessDeniedException(AuthorizationException): """Raised when no vendor context is available for an authenticated endpoint.""" def __init__(self, message: str = "No vendor context available"): super().__init__( message=message, error_code="VENDOR_ACCESS_DENIED", ) class VendorOwnerOnlyException(AuthorizationException): """Raised when operation requires vendor owner role.""" def __init__(self, operation: str, vendor_code: str | None = None): details = {"operation": operation} if vendor_code: details["vendor_code"] = vendor_code super().__init__( message=f"Operation '{operation}' requires vendor owner role", error_code="VENDOR_OWNER_ONLY", details=details, ) class InsufficientVendorPermissionsException(AuthorizationException): """Raised when user lacks required vendor permission.""" def __init__(self, required_permission: str, vendor_code: str | None = None): details = {"required_permission": required_permission} if vendor_code: details["vendor_code"] = vendor_code super().__init__( message=f"Permission required: {required_permission}", error_code="INSUFFICIENT_VENDOR_PERMISSIONS", details=details, )