updates
This commit is contained in:
@@ -16,6 +16,8 @@ from .favorite import Favorite
|
||||
from .audit_log import AuditLog
|
||||
from .cookie_policy import CookiePolicy
|
||||
from .cookie_integration_config import CookieIntegrationConfig
|
||||
from .system_settings import SystemSettings
|
||||
from .invoice import Invoice, InvoiceItem
|
||||
|
||||
__all__ = [
|
||||
"Role",
|
||||
@@ -36,5 +38,8 @@ __all__ = [
|
||||
"AuditLog",
|
||||
"CookiePolicy",
|
||||
"CookieIntegrationConfig",
|
||||
"SystemSettings",
|
||||
"Invoice",
|
||||
"InvoiceItem",
|
||||
]
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
Backend/src/models/__pycache__/invoice.cpython-312.pyc
Normal file
BIN
Backend/src/models/__pycache__/invoice.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Backend/src/models/__pycache__/system_settings.cpython-312.pyc
Normal file
BIN
Backend/src/models/__pycache__/system_settings.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
@@ -35,6 +35,7 @@ class Booking(Base):
|
||||
user = relationship("User", back_populates="bookings")
|
||||
room = relationship("Room", back_populates="bookings")
|
||||
payments = relationship("Payment", back_populates="booking", cascade="all, delete-orphan")
|
||||
invoices = relationship("Invoice", back_populates="booking", cascade="all, delete-orphan")
|
||||
service_usages = relationship("ServiceUsage", back_populates="booking", cascade="all, delete-orphan")
|
||||
checkin_checkout = relationship("CheckInCheckOut", back_populates="booking", uselist=False)
|
||||
|
||||
|
||||
100
Backend/src/models/invoice.py
Normal file
100
Backend/src/models/invoice.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Numeric, Text, Enum, ForeignKey, Boolean
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
import enum
|
||||
from ..config.database import Base
|
||||
|
||||
|
||||
class InvoiceStatus(str, enum.Enum):
|
||||
draft = "draft"
|
||||
sent = "sent"
|
||||
paid = "paid"
|
||||
overdue = "overdue"
|
||||
cancelled = "cancelled"
|
||||
|
||||
|
||||
class Invoice(Base):
|
||||
__tablename__ = "invoices"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
||||
invoice_number = Column(String(50), unique=True, nullable=False, index=True)
|
||||
booking_id = Column(Integer, ForeignKey("bookings.id"), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
||||
|
||||
# Invoice details
|
||||
issue_date = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
due_date = Column(DateTime, nullable=False)
|
||||
paid_date = Column(DateTime, nullable=True)
|
||||
|
||||
# Amounts
|
||||
subtotal = Column(Numeric(10, 2), nullable=False, default=0.00)
|
||||
tax_rate = Column(Numeric(5, 2), nullable=False, default=0.00) # Tax percentage
|
||||
tax_amount = Column(Numeric(10, 2), nullable=False, default=0.00)
|
||||
discount_amount = Column(Numeric(10, 2), nullable=False, default=0.00)
|
||||
total_amount = Column(Numeric(10, 2), nullable=False)
|
||||
amount_paid = Column(Numeric(10, 2), nullable=False, default=0.00)
|
||||
balance_due = Column(Numeric(10, 2), nullable=False)
|
||||
|
||||
# Status
|
||||
status = Column(Enum(InvoiceStatus), nullable=False, default=InvoiceStatus.draft)
|
||||
|
||||
# Company/Organization information (for admin to manage)
|
||||
company_name = Column(String(200), nullable=True)
|
||||
company_address = Column(Text, nullable=True)
|
||||
company_phone = Column(String(50), nullable=True)
|
||||
company_email = Column(String(100), nullable=True)
|
||||
company_tax_id = Column(String(100), nullable=True)
|
||||
company_logo_url = Column(String(500), nullable=True)
|
||||
|
||||
# Customer information (snapshot at invoice creation)
|
||||
customer_name = Column(String(200), nullable=False)
|
||||
customer_email = Column(String(100), nullable=False)
|
||||
customer_address = Column(Text, nullable=True)
|
||||
customer_phone = Column(String(50), nullable=True)
|
||||
customer_tax_id = Column(String(100), nullable=True)
|
||||
|
||||
# Additional information
|
||||
notes = Column(Text, nullable=True)
|
||||
terms_and_conditions = Column(Text, nullable=True)
|
||||
payment_instructions = Column(Text, nullable=True)
|
||||
|
||||
# Metadata
|
||||
created_by_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
updated_by_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||||
|
||||
# Relationships
|
||||
booking = relationship("Booking", back_populates="invoices")
|
||||
user = relationship("User", foreign_keys=[user_id], backref="invoices")
|
||||
created_by = relationship("User", foreign_keys=[created_by_id])
|
||||
updated_by = relationship("User", foreign_keys=[updated_by_id])
|
||||
items = relationship("InvoiceItem", back_populates="invoice", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class InvoiceItem(Base):
|
||||
__tablename__ = "invoice_items"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
||||
invoice_id = Column(Integer, ForeignKey("invoices.id"), nullable=False)
|
||||
|
||||
# Item details
|
||||
description = Column(String(500), nullable=False)
|
||||
quantity = Column(Numeric(10, 2), nullable=False, default=1.00)
|
||||
unit_price = Column(Numeric(10, 2), nullable=False)
|
||||
tax_rate = Column(Numeric(5, 2), nullable=False, default=0.00)
|
||||
discount_amount = Column(Numeric(10, 2), nullable=False, default=0.00)
|
||||
line_total = Column(Numeric(10, 2), nullable=False)
|
||||
|
||||
# Optional reference to booking items
|
||||
room_id = Column(Integer, ForeignKey("rooms.id"), nullable=True)
|
||||
service_id = Column(Integer, ForeignKey("services.id"), nullable=True)
|
||||
|
||||
# Metadata
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
|
||||
# Relationships
|
||||
invoice = relationship("Invoice", back_populates="items")
|
||||
room = relationship("Room")
|
||||
service = relationship("Service")
|
||||
|
||||
@@ -11,6 +11,7 @@ class PaymentMethod(str, enum.Enum):
|
||||
debit_card = "debit_card"
|
||||
bank_transfer = "bank_transfer"
|
||||
e_wallet = "e_wallet"
|
||||
stripe = "stripe"
|
||||
|
||||
|
||||
class PaymentType(str, enum.Enum):
|
||||
|
||||
@@ -22,6 +22,9 @@ class Room(Base):
|
||||
status = Column(Enum(RoomStatus), nullable=False, default=RoomStatus.available)
|
||||
price = Column(Numeric(10, 2), nullable=False)
|
||||
featured = Column(Boolean, nullable=False, default=False)
|
||||
capacity = Column(Integer, nullable=True) # Room-specific capacity, overrides room_type capacity
|
||||
room_size = Column(String(50), nullable=True) # e.g., "1 Room", "2 Rooms", "50 sqm"
|
||||
view = Column(String(100), nullable=True) # e.g., "City View", "Ocean View", etc.
|
||||
images = Column(JSON, nullable=True)
|
||||
amenities = Column(JSON, nullable=True)
|
||||
description = Column(Text, nullable=True)
|
||||
|
||||
21
Backend/src/models/system_settings.py
Normal file
21
Backend/src/models/system_settings.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Text, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
from ..config.database import Base
|
||||
|
||||
|
||||
class SystemSettings(Base):
|
||||
"""
|
||||
System-wide settings controlled by administrators.
|
||||
Stores key-value pairs for platform configuration like currency, etc.
|
||||
"""
|
||||
__tablename__ = "system_settings"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
||||
key = Column(String(100), unique=True, nullable=False, index=True)
|
||||
value = Column(Text, nullable=False)
|
||||
description = Column(Text, nullable=True)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||||
updated_by_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
updated_by = relationship("User", lazy="joined")
|
||||
|
||||
@@ -15,6 +15,7 @@ class User(Base):
|
||||
phone = Column(String(20), nullable=True)
|
||||
address = Column(Text, nullable=True)
|
||||
avatar = Column(String(255), nullable=True)
|
||||
currency = Column(String(3), nullable=False, default='VND') # ISO 4217 currency code
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
||||
|
||||
Reference in New Issue
Block a user