"""Phase ops — lightweight business documents for Sales/Purchase/Inventory UI.""" from __future__ import annotations import uuid from datetime import date from decimal import Decimal from sqlalchemy import Boolean, Date, Index, Numeric, String, Text, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column from app.core.database import Base from app.models.base import TenantMixin, TimestampMixin, UUIDPrimaryKeyMixin from app.models.types import GUID class BusinessDocument(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin): """Generic operational document used by Sales / Purchase / Inventory screens.""" __tablename__ = "business_documents" module: Mapped[str] = mapped_column(String(40), nullable=False) doc_type: Mapped[str] = mapped_column(String(50), nullable=False) number: Mapped[str] = mapped_column(String(50), nullable=False) doc_date: Mapped[date] = mapped_column(Date, nullable=False) party_name: Mapped[str | None] = mapped_column(String(255), nullable=True) party_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True) amount: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False) status: Mapped[str] = mapped_column(String(30), default="draft", nullable=False) description: Mapped[str | None] = mapped_column(Text, nullable=True) meta_json: Mapped[str | None] = mapped_column(Text, nullable=True) __table_args__ = ( UniqueConstraint("tenant_id", "module", "number", name="uq_biz_doc_tenant_module_number"), Index("ix_biz_doc_tenant_module_type", "tenant_id", "module", "doc_type"), ) class InventoryItem(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin): __tablename__ = "inventory_items" code: Mapped[str] = mapped_column(String(50), nullable=False) name: Mapped[str] = mapped_column(String(255), nullable=False) item_type: Mapped[str] = mapped_column(String(30), default="goods", nullable=False) unit: Mapped[str] = mapped_column(String(30), default="عدد", nullable=False) quantity_on_hand: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False) unit_cost: Mapped[Decimal] = mapped_column(Numeric(18, 4), default=Decimal("0"), nullable=False) is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) __table_args__ = ( UniqueConstraint("tenant_id", "code", name="uq_inventory_item_tenant_code"), ) class Warehouse(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin): __tablename__ = "warehouses" code: Mapped[str] = mapped_column(String(50), nullable=False) name: Mapped[str] = mapped_column(String(255), nullable=False) is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) __table_args__ = ( UniqueConstraint("tenant_id", "code", name="uq_warehouse_tenant_code"), )