initial commit
This commit is contained in:
commit
95b8af2360
15 changed files with 1519 additions and 0 deletions
117
migrations.py
Normal file
117
migrations.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
async def m001_initial(db):
|
||||
"""
|
||||
Initial migration for Castle accounting extension.
|
||||
Creates tables for double-entry bookkeeping system.
|
||||
"""
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE castle.accounts (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
account_type TEXT NOT NULL,
|
||||
description TEXT,
|
||||
user_id TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_accounts_user_id ON castle.accounts (user_id);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_accounts_type ON castle.accounts (account_type);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE castle.journal_entries (
|
||||
id TEXT PRIMARY KEY,
|
||||
description TEXT NOT NULL,
|
||||
entry_date TIMESTAMP NOT NULL,
|
||||
created_by TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now},
|
||||
reference TEXT
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_journal_entries_created_by ON castle.journal_entries (created_by);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_journal_entries_date ON castle.journal_entries (entry_date);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE castle.entry_lines (
|
||||
id TEXT PRIMARY KEY,
|
||||
journal_entry_id TEXT NOT NULL,
|
||||
account_id TEXT NOT NULL,
|
||||
debit INTEGER NOT NULL DEFAULT 0,
|
||||
credit INTEGER NOT NULL DEFAULT 0,
|
||||
description TEXT,
|
||||
FOREIGN KEY (journal_entry_id) REFERENCES castle.journal_entries (id),
|
||||
FOREIGN KEY (account_id) REFERENCES castle.accounts (id)
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_entry_lines_journal_entry ON castle.entry_lines (journal_entry_id);
|
||||
"""
|
||||
)
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
CREATE INDEX idx_entry_lines_account ON castle.entry_lines (account_id);
|
||||
"""
|
||||
)
|
||||
|
||||
# Insert default chart of accounts
|
||||
default_accounts = [
|
||||
# Assets
|
||||
("cash", "Cash", "asset", "Cash on hand"),
|
||||
("bank", "Bank Account", "asset", "Bank account"),
|
||||
("lightning", "Lightning Balance", "asset", "Lightning Network balance"),
|
||||
("accounts_receivable", "Accounts Receivable", "asset", "Money owed to the Castle"),
|
||||
|
||||
# Liabilities
|
||||
("accounts_payable", "Accounts Payable", "liability", "Money owed by the Castle"),
|
||||
|
||||
# Equity
|
||||
("member_equity", "Member Equity", "equity", "Member contributions"),
|
||||
("retained_earnings", "Retained Earnings", "equity", "Accumulated profits"),
|
||||
|
||||
# Revenue
|
||||
("accommodation_revenue", "Accommodation Revenue", "revenue", "Revenue from stays"),
|
||||
("service_revenue", "Service Revenue", "revenue", "Revenue from services"),
|
||||
("other_revenue", "Other Revenue", "revenue", "Other revenue"),
|
||||
|
||||
# Expenses
|
||||
("utilities", "Utilities", "expense", "Electricity, water, internet"),
|
||||
("food", "Food & Supplies", "expense", "Food and supplies"),
|
||||
("maintenance", "Maintenance", "expense", "Repairs and maintenance"),
|
||||
("other_expense", "Other Expenses", "expense", "Miscellaneous expenses"),
|
||||
]
|
||||
|
||||
for acc_id, name, acc_type, desc in default_accounts:
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO castle.accounts (id, name, account_type, description)
|
||||
VALUES (:id, :name, :type, :description)
|
||||
""",
|
||||
{"id": acc_id, "name": name, "type": acc_type, "description": desc}
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue