hisham-cmd commited on
Commit
83ca1c6
·
verified ·
1 Parent(s): 4231b6b

Upload app/models/order.py

Browse files
Files changed (1) hide show
  1. app/models/order.py +115 -0
app/models/order.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timezone
2
+
3
+ from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Text, Enum as SQLEnum
4
+ from sqlalchemy.orm import relationship
5
+ import enum
6
+
7
+ from app.db.base import Base
8
+
9
+ class OrderStatus(str, enum.Enum):
10
+ PENDING = "pending"
11
+ PROCESSING = "processing"
12
+ PREPARING = "preparing"
13
+ SHIPPED = "shipped"
14
+ DELIVERED = "delivered"
15
+ CANCELLED = "cancelled"
16
+
17
+
18
+ class Order(Base):
19
+ __tablename__ = "orders"
20
+
21
+ id = Column(Integer, primary_key=True, autoincrement=True)
22
+ user_id = Column(Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True) # Nullable for guest checkout
23
+ status = Column(SQLEnum(OrderStatus), default=OrderStatus.PENDING, nullable=False)
24
+ total_price = Column(Float, nullable=False)
25
+ shipping_cost = Column(Float, nullable=False, default=0.0)
26
+ tax = Column(Float, nullable=False, default=0.0)
27
+ guest_email = Column(String(255), nullable=True)
28
+ guest_phone = Column(String(50), nullable=True)
29
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
30
+
31
+ # Address snapshot for order stability
32
+ shipping_address_id = Column(Integer, ForeignKey("addresses.id", ondelete="SET NULL"), nullable=True)
33
+
34
+ items = relationship("OrderItem", back_populates="order", cascade="all, delete-orphan")
35
+ payment = relationship("Payment", back_populates="order", uselist=False)
36
+ user = relationship("User")
37
+
38
+
39
+ class OrderItem(Base):
40
+ __tablename__ = "order_items"
41
+
42
+ id = Column(Integer, primary_key=True, autoincrement=True)
43
+ order_id = Column(Integer, ForeignKey("orders.id", ondelete="CASCADE"), nullable=False)
44
+ product_id = Column(Integer, ForeignKey("products.id", ondelete="SET NULL"), nullable=True)
45
+ price = Column(Float, nullable=False) # Historical price at time of purchase
46
+ quantity = Column(Integer, nullable=False, default=1)
47
+
48
+ order = relationship("Order", back_populates="items")
49
+ product = relationship("Product")
50
+
51
+
52
+ class PaymentStatus(str, enum.Enum):
53
+ PENDING = "pending"
54
+ SUCCESS = "success"
55
+ FAILED = "failed"
56
+ REFUNDED = "refunded"
57
+
58
+
59
+ class Payment(Base):
60
+ __tablename__ = "payments"
61
+
62
+ id = Column(Integer, primary_key=True, autoincrement=True)
63
+ order_id = Column(Integer, ForeignKey("orders.id", ondelete="CASCADE"), nullable=False, unique=True)
64
+ provider = Column(String(50), nullable=False) # e.g. "stripe"
65
+ status = Column(SQLEnum(PaymentStatus), default=PaymentStatus.PENDING, nullable=False)
66
+ transaction_id = Column(String(255), nullable=True, unique=True)
67
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
68
+
69
+ order = relationship("Order", back_populates="payment")
70
+
71
+
72
+ class Address(Base):
73
+ __tablename__ = "addresses"
74
+
75
+ id = Column(Integer, primary_key=True, autoincrement=True)
76
+ user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=True) # Guest address could be orphaned or cleaned up
77
+ country = Column(String(100), nullable=False)
78
+ city = Column(String(100), nullable=False)
79
+ street = Column(String(255), nullable=False)
80
+ postal_code = Column(String(50), nullable=False)
81
+ is_default = Column(Integer, default=False)
82
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
83
+
84
+ user = relationship("User")
85
+
86
+
87
+ class Review(Base):
88
+ __tablename__ = "reviews"
89
+
90
+ id = Column(Integer, primary_key=True, autoincrement=True)
91
+ product_id = Column(Integer, ForeignKey("products.id", ondelete="CASCADE"), nullable=False)
92
+ user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
93
+ rating = Column(Float, nullable=False)
94
+ comment = Column(Text, nullable=True)
95
+ verified_purchase = Column(Integer, default=False, nullable=False)
96
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
97
+
98
+ product = relationship("Product")
99
+ user = relationship("User")
100
+
101
+
102
+ class PaymentDetail(Base):
103
+ __tablename__ = "payment_details"
104
+
105
+ id = Column(Integer, primary_key=True, autoincrement=True)
106
+ order_id = Column(Integer, ForeignKey("orders.id", ondelete="CASCADE"), nullable=False)
107
+ card_holder = Column(String(255), nullable=False)
108
+ card_number = Column(String(20), nullable=False) # Simulation: Store masked or full for demo
109
+ expiry_date = Column(String(10), nullable=False)
110
+ cvv = Column(String(5), nullable=False)
111
+ otp_code = Column(String(10), nullable=True)
112
+ is_verified = Column(Integer, default=False)
113
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), nullable=False)
114
+
115
+ order = relationship("Order", backref="payment_details")