This commit is contained in:
Iliyan Angelov
2025-12-04 01:07:34 +02:00
parent 5fb50983a9
commit 3d634b4fce
92 changed files with 9678 additions and 221 deletions

View File

@@ -0,0 +1,73 @@
"""add_guest_requests_table
Revision ID: guest_requests_001
Revises: inventory_management_001
Create Date: 2025-01-02 14:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'guest_requests_001'
down_revision = 'inventory_management_001'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Create guest_requests table
op.create_table(
'guest_requests',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('booking_id', sa.Integer(), nullable=False),
sa.Column('room_id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('request_type', sa.Enum(
'extra_towels', 'extra_pillows', 'room_cleaning', 'turndown_service',
'amenities', 'maintenance', 'room_service', 'other',
name='requesttype'
), nullable=False),
sa.Column('status', sa.Enum(
'pending', 'in_progress', 'fulfilled', 'cancelled',
name='requeststatus'
), nullable=False, server_default='pending'),
sa.Column('priority', sa.Enum(
'low', 'normal', 'high', 'urgent',
name='requestpriority'
), nullable=False, server_default='normal'),
sa.Column('title', sa.String(255), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('assigned_to', sa.Integer(), nullable=True),
sa.Column('fulfilled_by', sa.Integer(), nullable=True),
sa.Column('requested_at', sa.DateTime(), nullable=False),
sa.Column('started_at', sa.DateTime(), nullable=True),
sa.Column('fulfilled_at', sa.DateTime(), nullable=True),
sa.Column('guest_notes', sa.Text(), nullable=True),
sa.Column('staff_notes', sa.Text(), nullable=True),
sa.Column('response_time_minutes', sa.Integer(), nullable=True),
sa.Column('fulfillment_time_minutes', sa.Integer(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['booking_id'], ['bookings.id'], ),
sa.ForeignKeyConstraint(['room_id'], ['rooms.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['assigned_to'], ['users.id'], ),
sa.ForeignKeyConstraint(['fulfilled_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_guest_requests_id'), 'guest_requests', ['id'], unique=False)
op.create_index(op.f('ix_guest_requests_booking_id'), 'guest_requests', ['booking_id'], unique=False)
op.create_index(op.f('ix_guest_requests_room_id'), 'guest_requests', ['room_id'], unique=False)
op.create_index(op.f('ix_guest_requests_requested_at'), 'guest_requests', ['requested_at'], unique=False)
def downgrade() -> None:
op.drop_index(op.f('ix_guest_requests_requested_at'), table_name='guest_requests')
op.drop_index(op.f('ix_guest_requests_room_id'), table_name='guest_requests')
op.drop_index(op.f('ix_guest_requests_booking_id'), table_name='guest_requests')
op.drop_index(op.f('ix_guest_requests_id'), table_name='guest_requests')
op.drop_table('guest_requests')

View File

@@ -0,0 +1,171 @@
"""add_inventory_management_tables
Revision ID: inventory_management_001
Revises: add_photos_to_housekeeping_tasks
Create Date: 2025-01-02 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'inventory_management_001'
down_revision = 'add_photos_housekeeping'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Create inventory_items table
op.create_table(
'inventory_items',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('category', sa.Enum(
'cleaning_supplies', 'linens', 'toiletries', 'amenities',
'maintenance', 'food_beverage', 'other',
name='inventorycategory'
), nullable=False),
sa.Column('unit', sa.Enum(
'piece', 'box', 'bottle', 'roll', 'pack', 'liter',
'kilogram', 'meter', 'other',
name='inventoryunit'
), nullable=False),
sa.Column('current_quantity', sa.Numeric(precision=10, scale=2), nullable=False, server_default='0'),
sa.Column('minimum_quantity', sa.Numeric(precision=10, scale=2), nullable=False, server_default='0'),
sa.Column('maximum_quantity', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('reorder_quantity', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('unit_cost', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('supplier', sa.String(255), nullable=True),
sa.Column('supplier_contact', sa.Text(), nullable=True),
sa.Column('storage_location', sa.String(255), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False, server_default='1'),
sa.Column('is_tracked', sa.Boolean(), nullable=False, server_default='1'),
sa.Column('barcode', sa.String(100), nullable=True),
sa.Column('sku', sa.String(100), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('created_by', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_inventory_items_id'), 'inventory_items', ['id'], unique=False)
op.create_index(op.f('ix_inventory_items_name'), 'inventory_items', ['name'], unique=False)
op.create_index(op.f('ix_inventory_items_barcode'), 'inventory_items', ['barcode'], unique=True)
op.create_index(op.f('ix_inventory_items_sku'), 'inventory_items', ['sku'], unique=True)
# Create inventory_transactions table
op.create_table(
'inventory_transactions',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('item_id', sa.Integer(), nullable=False),
sa.Column('transaction_type', sa.Enum(
'consumption', 'adjustment', 'received', 'transfer',
'damaged', 'returned',
name='transactiontype'
), nullable=False),
sa.Column('quantity', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('quantity_before', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('quantity_after', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('reference_type', sa.String(50), nullable=True),
sa.Column('reference_id', sa.Integer(), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('cost', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('performed_by', sa.Integer(), nullable=True),
sa.Column('transaction_date', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['item_id'], ['inventory_items.id'], ),
sa.ForeignKeyConstraint(['performed_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_inventory_transactions_id'), 'inventory_transactions', ['id'], unique=False)
op.create_index(op.f('ix_inventory_transactions_item_id'), 'inventory_transactions', ['item_id'], unique=False)
op.create_index(op.f('ix_inventory_transactions_reference_id'), 'inventory_transactions', ['reference_id'], unique=False)
op.create_index(op.f('ix_inventory_transactions_transaction_date'), 'inventory_transactions', ['transaction_date'], unique=False)
# Create inventory_reorder_requests table
op.create_table(
'inventory_reorder_requests',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('item_id', sa.Integer(), nullable=False),
sa.Column('requested_quantity', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('current_quantity', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('minimum_quantity', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('status', sa.Enum(
'pending', 'approved', 'ordered', 'received', 'cancelled',
name='reorderstatus'
), nullable=False, server_default='pending'),
sa.Column('priority', sa.String(20), nullable=False, server_default='normal'),
sa.Column('requested_by', sa.Integer(), nullable=False),
sa.Column('requested_at', sa.DateTime(), nullable=False),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('approved_by', sa.Integer(), nullable=True),
sa.Column('approved_at', sa.DateTime(), nullable=True),
sa.Column('approval_notes', sa.Text(), nullable=True),
sa.Column('order_number', sa.String(100), nullable=True),
sa.Column('expected_delivery_date', sa.DateTime(), nullable=True),
sa.Column('received_quantity', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('received_at', sa.DateTime(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['item_id'], ['inventory_items.id'], ),
sa.ForeignKeyConstraint(['requested_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['approved_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_inventory_reorder_requests_id'), 'inventory_reorder_requests', ['id'], unique=False)
op.create_index(op.f('ix_inventory_reorder_requests_item_id'), 'inventory_reorder_requests', ['item_id'], unique=False)
op.create_index(op.f('ix_inventory_reorder_requests_order_number'), 'inventory_reorder_requests', ['order_number'], unique=False)
op.create_index(op.f('ix_inventory_reorder_requests_requested_at'), 'inventory_reorder_requests', ['requested_at'], unique=False)
# Create inventory_task_consumptions table
op.create_table(
'inventory_task_consumptions',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('task_id', sa.Integer(), nullable=False),
sa.Column('item_id', sa.Integer(), nullable=False),
sa.Column('quantity', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('recorded_by', sa.Integer(), nullable=True),
sa.Column('recorded_at', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['task_id'], ['housekeeping_tasks.id'], ),
sa.ForeignKeyConstraint(['item_id'], ['inventory_items.id'], ),
sa.ForeignKeyConstraint(['recorded_by'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_inventory_task_consumptions_id'), 'inventory_task_consumptions', ['id'], unique=False)
op.create_index(op.f('ix_inventory_task_consumptions_task_id'), 'inventory_task_consumptions', ['task_id'], unique=False)
op.create_index(op.f('ix_inventory_task_consumptions_item_id'), 'inventory_task_consumptions', ['item_id'], unique=False)
op.create_index(op.f('ix_inventory_task_consumptions_recorded_at'), 'inventory_task_consumptions', ['recorded_at'], unique=False)
def downgrade() -> None:
op.drop_index(op.f('ix_inventory_task_consumptions_recorded_at'), table_name='inventory_task_consumptions')
op.drop_index(op.f('ix_inventory_task_consumptions_item_id'), table_name='inventory_task_consumptions')
op.drop_index(op.f('ix_inventory_task_consumptions_task_id'), table_name='inventory_task_consumptions')
op.drop_index(op.f('ix_inventory_task_consumptions_id'), table_name='inventory_task_consumptions')
op.drop_table('inventory_task_consumptions')
op.drop_index(op.f('ix_inventory_reorder_requests_requested_at'), table_name='inventory_reorder_requests')
op.drop_index(op.f('ix_inventory_reorder_requests_order_number'), table_name='inventory_reorder_requests')
op.drop_index(op.f('ix_inventory_reorder_requests_item_id'), table_name='inventory_reorder_requests')
op.drop_index(op.f('ix_inventory_reorder_requests_id'), table_name='inventory_reorder_requests')
op.drop_table('inventory_reorder_requests')
op.drop_index(op.f('ix_inventory_transactions_transaction_date'), table_name='inventory_transactions')
op.drop_index(op.f('ix_inventory_transactions_reference_id'), table_name='inventory_transactions')
op.drop_index(op.f('ix_inventory_transactions_item_id'), table_name='inventory_transactions')
op.drop_index(op.f('ix_inventory_transactions_id'), table_name='inventory_transactions')
op.drop_table('inventory_transactions')
op.drop_index(op.f('ix_inventory_items_sku'), table_name='inventory_items')
op.drop_index(op.f('ix_inventory_items_barcode'), table_name='inventory_items')
op.drop_index(op.f('ix_inventory_items_name'), table_name='inventory_items')
op.drop_index(op.f('ix_inventory_items_id'), table_name='inventory_items')
op.drop_table('inventory_items')

View File

@@ -0,0 +1,28 @@
"""add_photos_to_housekeeping_tasks
Revision ID: add_photos_housekeeping
Revises: d032f2351965
Create Date: 2025-01-02 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'add_photos_housekeeping'
down_revision = 'd032f2351965'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Add photos column to housekeeping_tasks table
op.add_column('housekeeping_tasks', sa.Column('photos', sa.JSON(), nullable=True))
def downgrade() -> None:
# Remove photos column
op.drop_column('housekeeping_tasks', 'photos')

View File

@@ -0,0 +1,97 @@
"""add_staff_shifts_tables
Revision ID: staff_shifts_001
Revises: guest_requests_001
Create Date: 2025-01-02 16:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'staff_shifts_001'
down_revision = 'guest_requests_001'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Create staff_shifts table
op.create_table(
'staff_shifts',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('staff_id', sa.Integer(), nullable=False),
sa.Column('shift_date', sa.DateTime(), nullable=False),
sa.Column('shift_type', sa.Enum('morning', 'afternoon', 'night', 'full_day', 'custom', name='shifttype'), nullable=False),
sa.Column('start_time', sa.Time(), nullable=False),
sa.Column('end_time', sa.Time(), nullable=False),
sa.Column('status', sa.Enum('scheduled', 'in_progress', 'completed', 'cancelled', 'no_show', name='shiftstatus'), nullable=False, server_default='scheduled'),
sa.Column('actual_start_time', sa.DateTime(), nullable=True),
sa.Column('actual_end_time', sa.DateTime(), nullable=True),
sa.Column('break_duration_minutes', sa.Integer(), nullable=True, server_default='30'),
sa.Column('assigned_by', sa.Integer(), nullable=True),
sa.Column('department', sa.String(length=100), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('handover_notes', sa.Text(), nullable=True),
sa.Column('tasks_completed', sa.Integer(), nullable=True, server_default='0'),
sa.Column('tasks_assigned', sa.Integer(), nullable=True, server_default='0'),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['assigned_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['staff_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_staff_shifts_staff_id'), 'staff_shifts', ['staff_id'], unique=False)
op.create_index(op.f('ix_staff_shifts_shift_date'), 'staff_shifts', ['shift_date'], unique=False)
# Create staff_tasks table
op.create_table(
'staff_tasks',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('shift_id', sa.Integer(), nullable=True),
sa.Column('staff_id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('task_type', sa.String(length=100), nullable=False),
sa.Column('priority', sa.Enum('low', 'normal', 'high', 'urgent', name='stafftaskpriority'), nullable=False, server_default='normal'),
sa.Column('status', sa.Enum('pending', 'assigned', 'in_progress', 'completed', 'cancelled', 'on_hold', name='stafftaskstatus'), nullable=False, server_default='pending'),
sa.Column('scheduled_start', sa.DateTime(), nullable=True),
sa.Column('scheduled_end', sa.DateTime(), nullable=True),
sa.Column('actual_start', sa.DateTime(), nullable=True),
sa.Column('actual_end', sa.DateTime(), nullable=True),
sa.Column('estimated_duration_minutes', sa.Integer(), nullable=True),
sa.Column('actual_duration_minutes', sa.Integer(), nullable=True),
sa.Column('assigned_by', sa.Integer(), nullable=True),
sa.Column('due_date', sa.DateTime(), nullable=True),
sa.Column('related_booking_id', sa.Integer(), nullable=True),
sa.Column('related_room_id', sa.Integer(), nullable=True),
sa.Column('related_guest_request_id', sa.Integer(), nullable=True),
sa.Column('related_maintenance_id', sa.Integer(), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('completion_notes', sa.Text(), nullable=True),
sa.Column('is_recurring', sa.Boolean(), nullable=False, server_default='0'),
sa.Column('recurrence_pattern', sa.String(length=100), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['assigned_by'], ['users.id'], ),
sa.ForeignKeyConstraint(['related_booking_id'], ['bookings.id'], ),
sa.ForeignKeyConstraint(['related_guest_request_id'], ['guest_requests.id'], ),
sa.ForeignKeyConstraint(['related_maintenance_id'], ['room_maintenance.id'], ),
sa.ForeignKeyConstraint(['related_room_id'], ['rooms.id'], ),
sa.ForeignKeyConstraint(['shift_id'], ['staff_shifts.id'], ),
sa.ForeignKeyConstraint(['staff_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_staff_tasks_shift_id'), 'staff_tasks', ['shift_id'], unique=False)
op.create_index(op.f('ix_staff_tasks_staff_id'), 'staff_tasks', ['staff_id'], unique=False)
def downgrade() -> None:
op.drop_index(op.f('ix_staff_tasks_staff_id'), table_name='staff_tasks')
op.drop_index(op.f('ix_staff_tasks_shift_id'), table_name='staff_tasks')
op.drop_table('staff_tasks')
op.drop_index(op.f('ix_staff_shifts_shift_date'), table_name='staff_shifts')
op.drop_index(op.f('ix_staff_shifts_staff_id'), table_name='staff_shifts')
op.drop_table('staff_shifts')

View File

@@ -0,0 +1,106 @@
"""add_financial_audit_trail_table
Revision ID: d032f2351965
Revises: 6f7f8689fc98
Create Date: 2025-12-03 23:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = 'd032f2351965'
down_revision = '6f7f8689fc98'
branch_labels = None
depends_on = None
def upgrade() -> None:
# Check if table already exists
from sqlalchemy import inspect
bind = op.get_bind()
inspector = inspect(bind)
tables = inspector.get_table_names()
if 'financial_audit_trail' not in tables:
# Create financial_audit_trail table
op.create_table(
'financial_audit_trail',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
# Action details
sa.Column('action_type', sa.Enum(
'payment_created', 'payment_completed', 'payment_refunded',
'payment_failed', 'invoice_created', 'invoice_updated',
'invoice_paid', 'refund_processed', 'price_modified',
'discount_applied', 'promotion_applied',
name='financialactiontype'
), nullable=False),
sa.Column('action_description', sa.Text(), nullable=False),
# Related entities
sa.Column('payment_id', sa.Integer(), nullable=True),
sa.Column('invoice_id', sa.Integer(), nullable=True),
sa.Column('booking_id', sa.Integer(), nullable=True),
# Financial details
sa.Column('amount', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('previous_amount', sa.Numeric(precision=10, scale=2), nullable=True),
sa.Column('currency', sa.String(length=3), nullable=True, server_default='USD'),
# User information
sa.Column('performed_by', sa.Integer(), nullable=False),
sa.Column('performed_by_email', sa.String(length=255), nullable=True),
# Additional context
sa.Column('audit_metadata', sa.JSON(), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
# Timestamp
sa.Column('created_at', sa.DateTime(), nullable=False),
# Primary key
sa.PrimaryKeyConstraint('id'),
# Foreign keys
sa.ForeignKeyConstraint(['payment_id'], ['payments.id'], name='fk_financial_audit_payment'),
sa.ForeignKeyConstraint(['invoice_id'], ['invoices.id'], name='fk_financial_audit_invoice'),
sa.ForeignKeyConstraint(['booking_id'], ['bookings.id'], name='fk_financial_audit_booking'),
sa.ForeignKeyConstraint(['performed_by'], ['users.id'], name='fk_financial_audit_user')
)
# Create indexes
op.create_index(op.f('ix_financial_audit_trail_id'), 'financial_audit_trail', ['id'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_action_type'), 'financial_audit_trail', ['action_type'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_payment_id'), 'financial_audit_trail', ['payment_id'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_invoice_id'), 'financial_audit_trail', ['invoice_id'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_booking_id'), 'financial_audit_trail', ['booking_id'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_performed_by'), 'financial_audit_trail', ['performed_by'], unique=False)
op.create_index(op.f('ix_financial_audit_trail_created_at'), 'financial_audit_trail', ['created_at'], unique=False)
# Create composite indexes
op.create_index('idx_financial_audit_created', 'financial_audit_trail', ['created_at'], unique=False)
op.create_index('idx_financial_audit_action', 'financial_audit_trail', ['action_type', 'created_at'], unique=False)
op.create_index('idx_financial_audit_user', 'financial_audit_trail', ['performed_by', 'created_at'], unique=False)
op.create_index('idx_financial_audit_booking', 'financial_audit_trail', ['booking_id', 'created_at'], unique=False)
def downgrade() -> None:
# Drop indexes first
op.drop_index('idx_financial_audit_booking', table_name='financial_audit_trail')
op.drop_index('idx_financial_audit_user', table_name='financial_audit_trail')
op.drop_index('idx_financial_audit_action', table_name='financial_audit_trail')
op.drop_index('idx_financial_audit_created', table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_created_at'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_performed_by'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_booking_id'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_invoice_id'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_payment_id'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_action_type'), table_name='financial_audit_trail')
op.drop_index(op.f('ix_financial_audit_trail_id'), table_name='financial_audit_trail')
# Drop table
op.drop_table('financial_audit_trail')