"""Hospitality foundation DTOs — Phase 12.0.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, Field from app.models.types import ( BundleKey, BundleStatus, LifecycleStatus, MenuStatus, TableStatus, VenueFormat, ) from app.schemas.common import ORMBase class VenueCreate(BaseModel): code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.DRAFT venue_format: VenueFormat = VenueFormat.RESTAURANT legal_name: str | None = Field(default=None, max_length=255) timezone: str = Field(default="Asia/Tehran", max_length=64) language: str = Field(default="fa", max_length=16) currency_code: str = Field(default="IRR", max_length=3) settings: dict | None = None class VenueUpdate(BaseModel): name: str | None = Field(default=None, max_length=255) description: str | None = None status: LifecycleStatus | None = None venue_format: VenueFormat | None = None legal_name: str | None = Field(default=None, max_length=255) timezone: str | None = Field(default=None, max_length=64) language: str | None = Field(default=None, max_length=16) currency_code: str | None = Field(default=None, max_length=3) settings: dict | None = None version: int | None = None class VenueRead(ORMBase): id: UUID tenant_id: UUID code: str name: str description: str | None status: LifecycleStatus venue_format: VenueFormat legal_name: str | None timezone: str language: str currency_code: str settings: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BranchCreate(BaseModel): venue_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE address: dict | None = None timezone: str | None = Field(default=None, max_length=64) working_hours: dict | None = None metadata_json: dict | None = None class BranchUpdate(BaseModel): name: str | None = Field(default=None, max_length=255) description: str | None = None status: LifecycleStatus | None = None address: dict | None = None timezone: str | None = Field(default=None, max_length=64) working_hours: dict | None = None metadata_json: dict | None = None class BranchRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID code: str name: str description: str | None status: LifecycleStatus address: dict | None timezone: str | None working_hours: dict | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class DiningAreaCreate(BaseModel): venue_id: UUID branch_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE sort_order: int = 0 metadata_json: dict | None = None class DiningAreaRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID branch_id: UUID | None code: str name: str description: str | None status: LifecycleStatus sort_order: int metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class DiningTableCreate(BaseModel): venue_id: UUID dining_area_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) capacity: int = 2 status: TableStatus = TableStatus.AVAILABLE qr_token: str | None = Field(default=None, max_length=100) metadata_json: dict | None = None class DiningTableRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID dining_area_id: UUID | None code: str name: str capacity: int status: TableStatus qr_token: str | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class MenuCreate(BaseModel): venue_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: MenuStatus = MenuStatus.DRAFT currency_code: str = Field(default="IRR", max_length=3) is_default: bool = False metadata_json: dict | None = None class MenuUpdate(BaseModel): name: str | None = Field(default=None, max_length=255) description: str | None = None status: MenuStatus | None = None currency_code: str | None = Field(default=None, max_length=3) is_default: bool | None = None metadata_json: dict | None = None version: int | None = None class MenuRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID code: str name: str description: str | None status: MenuStatus currency_code: str is_default: bool metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class MenuCategoryCreate(BaseModel): venue_id: UUID menu_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE sort_order: int = 0 class MenuCategoryRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID menu_id: UUID code: str name: str description: str | None status: LifecycleStatus sort_order: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class MenuItemCreate(BaseModel): venue_id: UUID menu_id: UUID category_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE base_price: int = 0 currency_code: str = Field(default="IRR", max_length=3) is_available: bool = True sort_order: int = 0 attributes: dict | None = None preparation_minutes: int | None = None calories: int | None = None spicy_level: int = 0 is_vegetarian: bool = False is_vegan: bool = False is_gluten_free: bool = False tags: list[str] | None = None primary_media_ref: str | None = Field(default=None, max_length=255) class MenuItemRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID menu_id: UUID category_id: UUID | None code: str name: str description: str | None status: LifecycleStatus base_price: int currency_code: str is_available: bool sort_order: int attributes: dict | None preparation_minutes: int | None calories: int | None spicy_level: int is_vegetarian: bool is_vegan: bool is_gluten_free: bool tags: list | None primary_media_ref: str | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class BundleDefinitionCreate(BaseModel): code: str = Field(max_length=50) bundle_key: BundleKey name: str = Field(max_length=255) description: str | None = None status: BundleStatus = BundleStatus.AVAILABLE feature_keys: list[str] | None = None permission_prefixes: list[str] | None = None api_prefixes: list[str] | None = None metadata_json: dict | None = None class BundleDefinitionRead(ORMBase): id: UUID tenant_id: UUID code: str bundle_key: BundleKey name: str description: str | None status: BundleStatus feature_keys: list | None permission_prefixes: list | None api_prefixes: list | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class TenantBundleActivate(BaseModel): bundle_definition_id: UUID venue_id: UUID | None = None metadata_json: dict | None = None class TenantBundleRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID | None bundle_definition_id: UUID bundle_key: BundleKey status: BundleStatus activated_by: str | None metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class FeatureToggleUpsert(BaseModel): feature_key: str = Field(max_length=100) enabled: bool = False venue_id: UUID | None = None bundle_key: BundleKey | None = None metadata_json: dict | None = None class FeatureToggleRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID | None feature_key: str enabled: bool bundle_key: BundleKey | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class HospitalityRoleCreate(BaseModel): venue_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) description: str | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE permission_keys: list[str] | None = None class HospitalityRoleRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID | None code: str name: str description: str | None status: LifecycleStatus permission_keys: list | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class HospitalityPermissionCreate(BaseModel): code: str = Field(max_length=100) name: str = Field(max_length=255) description: str | None = None bundle_key: BundleKey | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE class HospitalityPermissionRead(ORMBase): id: UUID tenant_id: UUID code: str name: str description: str | None bundle_key: BundleKey | None status: LifecycleStatus is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class HospitalityConfigurationCreate(BaseModel): venue_id: UUID | None = None branch_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) config: dict | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE class HospitalityConfigurationUpdate(BaseModel): name: str | None = Field(default=None, max_length=255) config: dict | None = None status: LifecycleStatus | None = None version: int | None = None class HospitalityConfigurationRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID | None branch_id: UUID | None code: str name: str config: dict | None status: LifecycleStatus version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class HospitalityEventCreate(BaseModel): venue_id: UUID event_type: str = Field(max_length=100) title: str = Field(max_length=255) payload: dict | None = None status: LifecycleStatus = LifecycleStatus.ACTIVE class HospitalityEventRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID event_type: str title: str payload: dict | None status: LifecycleStatus is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class HospitalitySettingUpsert(BaseModel): key: str = Field(max_length=100) value: dict | None = None venue_id: UUID | None = None class HospitalitySettingRead(ORMBase): id: UUID tenant_id: UUID venue_id: UUID | None key: str value: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime