from __future__ import annotations from datetime import datetime from decimal import Decimal from typing import Any from sqlalchemy import DateTime, ForeignKey, Index, Integer, Numeric, String, Text, UniqueConstraint, text from sqlalchemy.types import JSON from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import BaseModel, ID_TYPE, TimestampMixin class Household(BaseModel, TimestampMixin): __tablename__ = "households" __table_args__ = ( UniqueConstraint("household_code", name="uk_households_household_code"), Index( "uk_households_head_name_active", "head_name", unique=True, sqlite_where=text("deleted_at IS NULL"), ), Index("idx_households_head_name", "head_name"), Index("idx_households_phone", "phone"), Index( "idx_households_side_relation_category", "side", "relation_category_option_id", ), Index("idx_households_attendance_status", "attendance_status"), Index("idx_households_updated_at", "updated_at"), Index("idx_households_deleted_at", "deleted_at"), ) id: Mapped[int] = mapped_column(ID_TYPE, primary_key=True) household_code: Mapped[str] = mapped_column(String(32), nullable=False) head_name: Mapped[str] = mapped_column(String(64), nullable=False) phone: Mapped[str | None] = mapped_column(String(32), nullable=True) side: Mapped[str] = mapped_column(String(32), nullable=False, default="groom_side") relation_category_option_id: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("option_items.id", ondelete="RESTRICT"), nullable=True, ) relation_detail_option_id: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("option_items.id", ondelete="RESTRICT"), nullable=True, ) tag_option_ids_json: Mapped[list[int] | None] = mapped_column(JSON, nullable=True) invite_status: Mapped[str] = mapped_column( String(32), nullable=False, default="not_invited", ) attendance_status: Mapped[str] = mapped_column( String(32), nullable=False, default="pending", ) expected_attendee_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) actual_attendee_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) child_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) red_packet_child_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) total_gift_amount: Mapped[Decimal] = mapped_column( Numeric(12, 2), nullable=False, default=Decimal("0.00"), ) gift_method_option_id: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("option_items.id", ondelete="RESTRICT"), nullable=True, ) gift_scene_option_id: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("option_items.id", ondelete="RESTRICT"), nullable=True, ) favor_status: Mapped[str] = mapped_column( String(32), nullable=False, default="not_given", ) candy_status: Mapped[str] = mapped_column( String(32), nullable=False, default="not_given", ) child_red_packet_status: Mapped[str] = mapped_column( String(32), nullable=False, default="not_given", ) note: Mapped[str | None] = mapped_column(Text, nullable=True) created_by: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("accounts.id", ondelete="SET NULL"), nullable=True, ) updated_by: Mapped[int | None] = mapped_column( ID_TYPE, ForeignKey("accounts.id", ondelete="SET NULL"), nullable=True, ) deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) version: Mapped[int] = mapped_column(Integer, nullable=False, default=1) created_by_account: Mapped[Any] = relationship( "Account", foreign_keys=[created_by], back_populates="created_households", ) updated_by_account: Mapped[Any] = relationship( "Account", foreign_keys=[updated_by], back_populates="updated_households", ) relation_category_option: Mapped[Any] = relationship( "OptionItem", foreign_keys=[relation_category_option_id], back_populates="households_as_relation_category", ) relation_detail_option: Mapped[Any] = relationship( "OptionItem", foreign_keys=[relation_detail_option_id], back_populates="households_as_relation_detail", ) gift_method_option: Mapped[Any] = relationship( "OptionItem", foreign_keys=[gift_method_option_id], back_populates="households_as_gift_method", ) gift_scene_option: Mapped[Any] = relationship( "OptionItem", foreign_keys=[gift_scene_option_id], back_populates="households_as_gift_scene", ) members: Mapped[list[Any]] = relationship( "HouseholdMember", back_populates="household", ) gift_records: Mapped[list[Any]] = relationship( "GiftRecord", back_populates="household", )