from datetime import datetime from decimal import Decimal from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Text, JSON, Numeric from sqlalchemy.orm import relationship from app.core.database import Base from .base import TimestampMixin class Customer(Base, TimestampMixin): __tablename__ = "customers" id = Column(Integer, primary_key=True, index=True) vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=False) email = Column(String(255), nullable=False, index=True) # Unique within vendor scope hashed_password = Column(String(255), nullable=False) first_name = Column(String(100)) last_name = Column(String(100)) phone = Column(String(50)) customer_number = Column(String(100), nullable=False, index=True) # Vendor-specific ID preferences = Column(JSON, default=dict) marketing_consent = Column(Boolean, default=False) last_order_date = Column(DateTime) total_orders = Column(Integer, default=0) total_spent = Column(Numeric(10, 2), default=0) is_active = Column(Boolean, default=True, nullable=False) # Relationships vendor = relationship("Vendor", back_populates="customers") addresses = relationship("CustomerAddress", back_populates="customer") orders = relationship("Order", back_populates="customer") def __repr__(self): return f"" @property def full_name(self): if self.first_name and self.last_name: return f"{self.first_name} {self.last_name}" return self.email class CustomerAddress(Base, TimestampMixin): __tablename__ = "customer_addresses" id = Column(Integer, primary_key=True, index=True) vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=False) customer_id = Column(Integer, ForeignKey("customers.id"), nullable=False) address_type = Column(String(50), nullable=False) # 'billing', 'shipping' first_name = Column(String(100), nullable=False) last_name = Column(String(100), nullable=False) company = Column(String(200)) address_line_1 = Column(String(255), nullable=False) address_line_2 = Column(String(255)) city = Column(String(100), nullable=False) postal_code = Column(String(20), nullable=False) country = Column(String(100), nullable=False) is_default = Column(Boolean, default=False) # Relationships vendor = relationship("Vendor") customer = relationship("Customer", back_populates="addresses") def __repr__(self): return f""