# /opt/docker/dev/service_finder/backend/app/models/fleet/organization.py """ fleet schema: B2B kapcsolatok és kapcsolattartók. - OrganizationRelationship: Két szervezet közötti B2B kapcsolat (vevő, beszállító, partner) - ContactPerson: Szervezethez tartozó kapcsolattartó személy """ from __future__ import annotations from datetime import datetime from typing import Optional, TYPE_CHECKING from sqlalchemy import ( String, Boolean, DateTime, ForeignKey, Numeric, Text, Integer, BigInteger, text ) from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from app.database import Base if TYPE_CHECKING: from app.models.marketplace.organization import Organization from app.models.identity.identity import Person # ============================================================================= # OrganizationRelationship # ============================================================================= class OrganizationRelationship(Base): """ Két szervezet közötti B2B kapcsolat. Lehetővé teszi a vevő-beszállító, partneri kapcsolatok nyilvántartását anélkül, hogy a szervezet rekordokat duplikálni kellene. """ __tablename__ = "org_relationships" __table_args__ = {"schema": "fleet"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) # A kapcsolat két oldala source_org_id: Mapped[int] = mapped_column( Integer, ForeignKey("fleet.organizations.id"), nullable=False, index=True ) target_org_id: Mapped[int] = mapped_column( Integer, ForeignKey("fleet.organizations.id"), nullable=False, index=True ) # Kapcsolat típusa relationship_type: Mapped[str] = mapped_column( String(30), nullable=False, comment="CUSTOMER, SUPPLIER, PARTNER" ) # Státusz status: Mapped[str] = mapped_column( String(20), default="ACTIVE", server_default=text("'ACTIVE'") ) # Szerződéses adatok contract_ref: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) valid_from: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True) valid_until: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True) # Pénzügyi feltételek credit_limit: Mapped[Optional[float]] = mapped_column(Numeric(18, 2), nullable=True) payment_terms: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) # Megjegyzések notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True) # Időbélyegek created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[Optional[datetime]] = mapped_column( DateTime(timezone=True), onupdate=func.now(), server_default=func.now() ) # Kapcsolatok source_org: Mapped["Organization"] = relationship( "Organization", foreign_keys=[source_org_id] ) target_org: Mapped["Organization"] = relationship( "Organization", foreign_keys=[target_org_id] ) def __repr__(self) -> str: return ( f"OrganizationRelationship(id={self.id}, " f"source={self.source_org_id}, target={self.target_org_id}, " f"type='{self.relationship_type}')" ) # ============================================================================= # ContactPerson # ============================================================================= class ContactPerson(Base): """ Kapcsolattartó személy egy szervezethez. A személy rekord az identity.persons táblában él, ez a modell csak a szervezeti kapcsolatot és szerepkört tárolja. """ __tablename__ = "contact_persons" __table_args__ = {"schema": "fleet"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) # Melyik szervezethez tartozik organization_id: Mapped[int] = mapped_column( Integer, ForeignKey("fleet.organizations.id"), nullable=False, index=True ) # Hivatkozás a személy rekordra (identity sémában) person_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("identity.persons.id"), nullable=False, index=True ) # Szerepkör a szervezetben (pl. "CEO", "Fleet Manager", "Accountant") role: Mapped[str] = mapped_column(String(50), nullable=False) # Elsődleges kapcsolattartó? is_primary: Mapped[bool] = mapped_column(Boolean, default=False, server_default=text("false")) # Részleg department: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) # Megjegyzések notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True) # Időbélyegek created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[Optional[datetime]] = mapped_column( DateTime(timezone=True), onupdate=func.now(), server_default=func.now() ) # Kapcsolatok organization: Mapped["Organization"] = relationship( "Organization", foreign_keys=[organization_id] ) person: Mapped["Person"] = relationship( "Person", foreign_keys=[person_id] ) def __repr__(self) -> str: return ( f"ContactPerson(id={self.id}, org_id={self.organization_id}, " f"person_id={self.person_id}, role='{self.role}')" )