mickeywu520's picture
first commit
cd9bca9
"""
SQLAlchemy 資料庫模型 - 基於進銷存系統
"""
from sqlalchemy import Column, Integer, String, Text, DECIMAL, Boolean, DateTime, ForeignKey, JSON, Date, Float, Enum
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from backend.database.connection import Base
import enum
# 枚舉類型定義
class UserRole(str, enum.Enum):
ADMIN = "ADMIN"
USER = "USER"
class TransactionType(str, enum.Enum):
PURCHASE = "PURCHASE"
SELL = "SELL"
class TransactionStatus(str, enum.Enum):
PENDING = "PENDING"
PROCESSING = "PROCESSING"
COMPLETED = "COMPLETED"
CANCELLED = "CANCELLED"
class PurchaseOrderStatus(str, enum.Enum):
DRAFT = "DRAFT"
PENDING = "PENDING"
CONFIRMED = "CONFIRMED"
RECEIVED = "RECEIVED"
CANCELLED = "CANCELLED"
class SalesOrderStatus(str, enum.Enum):
DRAFT = "DRAFT"
CONFIRMED = "CONFIRMED"
SHIPPED = "SHIPPED"
DELIVERED = "DELIVERED"
CANCELLED = "CANCELLED"
class PaymentStatus(str, enum.Enum):
UNPAID = "UNPAID"
PARTIAL = "PARTIAL"
PAID = "PAID"
# 基礎模型
class User(Base):
"""用戶模型"""
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255))
email = Column(String(255), unique=True, nullable=False)
phoneNumber = Column(String(50))
role = Column(Enum(UserRole), default=UserRole.USER)
createdAt = Column(DateTime(timezone=True), server_default=func.now())
# 關聯
purchase_orders = relationship("PurchaseOrder", back_populates="purchaser")
sales_orders = relationship("SalesOrder", back_populates="salesperson")
class Category(Base):
"""商品類別模型"""
__tablename__ = "categories"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255), nullable=False)
# 關聯
products = relationship("Product", back_populates="category")
class Product(Base):
"""商品模型"""
__tablename__ = "products"
id = Column(Integer, primary_key=True, autoincrement=True)
productCode = Column(String(100), unique=True, nullable=False)
productName = Column(String(255), nullable=False)
unit = Column(String(50), nullable=False)
warehouse = Column(String(100))
unitWeight = Column(Float)
barcode = Column(String(100))
category_id = Column(Integer, ForeignKey("categories.id"))
stock = Column(Integer, default=0)
is_deleted = Column(Boolean, default=False)
deleted_at = Column(DateTime(timezone=True))
deleted_by = Column(Integer)
createdAt = Column(DateTime(timezone=True), server_default=func.now())
updatedAt = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
category = relationship("Category", back_populates="products")
purchase_order_items = relationship("PurchaseOrderItem", back_populates="product")
sales_order_items = relationship("SalesOrderItem", back_populates="product")
class Supplier(Base):
"""供應商模型"""
__tablename__ = "suppliers"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(255), nullable=False)
contactInfo = Column(Text)
address = Column(Text)
# 關聯
purchase_orders = relationship("PurchaseOrder", back_populates="supplier")
class Customer(Base):
"""客戶模型"""
__tablename__ = "customers"
id = Column(Integer, primary_key=True, autoincrement=True)
customerType = Column(String(100))
salesPersonId = Column(String(100))
salesPersonName = Column(String(255))
customerCode = Column(String(100), unique=True, nullable=False)
customerName = Column(String(255), nullable=False)
contactPerson = Column(String(255))
invoiceTitle = Column(String(255))
taxId = Column(String(50))
phoneNumber = Column(String(50))
faxNumber = Column(String(50))
deliveryAddress = Column(Text)
businessHours = Column(String(255))
paymentMethod = Column(String(100))
paymentCategory = Column(String(100))
creditLimit = Column(Float, default=0.0)
createdDate = Column(DateTime(timezone=True), server_default=func.now())
updatedAt = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
sales_orders = relationship("SalesOrder", back_populates="customer")
class PurchaseOrder(Base):
"""採購單模型"""
__tablename__ = "purchase_orders"
id = Column(Integer, primary_key=True, autoincrement=True)
po_number = Column(String(100), unique=True, nullable=False)
purchase_date = Column(Date, nullable=False)
expected_delivery_date = Column(Date)
supplier_id = Column(Integer, ForeignKey("suppliers.id"))
purchaser_id = Column(Integer, ForeignKey("users.id"))
status = Column(Enum(PurchaseOrderStatus), default=PurchaseOrderStatus.DRAFT)
subtotal = Column(Float, default=0.0)
tax_amount = Column(Float, default=0.0)
total_amount = Column(Float, default=0.0)
payment_status = Column(Enum(PaymentStatus), default=PaymentStatus.UNPAID)
notes = Column(Text)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
supplier = relationship("Supplier", back_populates="purchase_orders")
purchaser = relationship("User", back_populates="purchase_orders")
items = relationship("PurchaseOrderItem", back_populates="purchase_order")
class PurchaseOrderItem(Base):
"""採購單明細模型"""
__tablename__ = "purchase_order_items"
id = Column(Integer, primary_key=True, autoincrement=True)
purchase_order_id = Column(Integer, ForeignKey("purchase_orders.id"))
product_id = Column(Integer, ForeignKey("products.id"))
quantity = Column(Integer, nullable=False)
unit_price = Column(Float, nullable=False)
line_total = Column(Float, nullable=False)
notes = Column(Text)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
purchase_order = relationship("PurchaseOrder", back_populates="items")
product = relationship("Product", back_populates="purchase_order_items")
class SalesOrder(Base):
"""銷售單模型"""
__tablename__ = "sales_orders"
id = Column(Integer, primary_key=True, autoincrement=True)
so_number = Column(String(100), unique=True, nullable=False)
sales_date = Column(Date, nullable=False)
customer_id = Column(Integer, ForeignKey("customers.id"))
salesperson_id = Column(Integer, ForeignKey("users.id"))
status = Column(Enum(SalesOrderStatus), default=SalesOrderStatus.DRAFT)
subtotal = Column(Float, default=0.0)
tax_amount = Column(Float, default=0.0)
discount_amount = Column(Float, default=0.0)
total_amount = Column(Float, default=0.0)
notes = Column(Text)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
customer = relationship("Customer", back_populates="sales_orders")
salesperson = relationship("User", back_populates="sales_orders")
items = relationship("SalesOrderItem", back_populates="sales_order")
class SalesOrderItem(Base):
"""銷售單明細模型"""
__tablename__ = "sales_order_items"
id = Column(Integer, primary_key=True, autoincrement=True)
sales_order_id = Column(Integer, ForeignKey("sales_orders.id"))
product_id = Column(Integer, ForeignKey("products.id"))
quantity = Column(Integer, nullable=False)
unit_price = Column(Float, nullable=False)
line_total = Column(Float, nullable=False)
notes = Column(Text)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# 關聯
sales_order = relationship("SalesOrder", back_populates="items")
product = relationship("Product", back_populates="sales_order_items")
# LINE Bot 相關模型
class LineMessage(Base):
"""LINE 訊息記錄模型"""
__tablename__ = "line_messages"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String(255))
message = Column(Text, nullable=False)
message_type = Column(String(50), default="text")
timestamp = Column(DateTime(timezone=True), server_default=func.now())
processed = Column(Boolean, default=False)