-- Journal-Modul: Buchführungsjournal für PIRP -- Migration: Alle Journal-Tabellen erstellen -- Jahre CREATE TABLE IF NOT EXISTS journal_years ( id SERIAL PRIMARY KEY, year INTEGER NOT NULL UNIQUE, is_closed BOOLEAN NOT NULL DEFAULT FALSE, notes TEXT, created_at TIMESTAMPTZ DEFAULT now() ); -- Lieferanten CREATE TABLE IF NOT EXISTS journal_suppliers ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, sort_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT TRUE ); -- Erlös-/Wareneingang-Kategorien CREATE TABLE IF NOT EXISTS journal_revenue_categories ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, category_type VARCHAR(20) NOT NULL CHECK (category_type IN ('wareneingang', 'erloese')), vat_rate NUMERIC(5,2) NOT NULL DEFAULT 19.00, sort_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT TRUE ); -- Aufwandskategorien CREATE TABLE IF NOT EXISTS journal_expense_categories ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, side VARCHAR(10) NOT NULL DEFAULT 'soll' CHECK (side IN ('soll', 'soll_haben')), sort_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT TRUE ); -- Journal-Einträge (Buchungen) CREATE TABLE IF NOT EXISTS journal_entries ( id SERIAL PRIMARY KEY, year_id INTEGER NOT NULL REFERENCES journal_years(id) ON DELETE RESTRICT, entry_date DATE NOT NULL, month INTEGER NOT NULL CHECK (month BETWEEN 1 AND 12), description TEXT NOT NULL, attachment_note TEXT, amount NUMERIC(12,2) NOT NULL DEFAULT 0, supplier_id INTEGER REFERENCES journal_suppliers(id) ON DELETE SET NULL, sort_order INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMPTZ DEFAULT now() ); -- Kontenverteilung pro Buchung CREATE TABLE IF NOT EXISTS journal_entry_accounts ( id SERIAL PRIMARY KEY, entry_id INTEGER NOT NULL REFERENCES journal_entries(id) ON DELETE CASCADE, account_type VARCHAR(20) NOT NULL, side VARCHAR(5) NOT NULL CHECK (side IN ('soll', 'haben')), amount NUMERIC(12,2) NOT NULL DEFAULT 0, revenue_category_id INTEGER REFERENCES journal_revenue_categories(id) ON DELETE SET NULL, expense_category_id INTEGER REFERENCES journal_expense_categories(id) ON DELETE SET NULL, note TEXT ); -- Monatliche Zusammenfassung (manuelle Korrekturen) CREATE TABLE IF NOT EXISTS journal_monthly_summary ( id SERIAL PRIMARY KEY, year_id INTEGER NOT NULL REFERENCES journal_years(id) ON DELETE CASCADE, month INTEGER NOT NULL CHECK (month BETWEEN 1 AND 12), manual_corrections JSONB DEFAULT '{}', notes TEXT, UNIQUE(year_id, month) ); -- Umsatz-Zusammenfassungsposten (z.B. "Reinigung", "RMV", "Handy") CREATE TABLE IF NOT EXISTS journal_summary_items ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, sort_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT TRUE ); -- Monatliche Werte für Zusammenfassungsposten CREATE TABLE IF NOT EXISTS journal_monthly_summary_values ( id SERIAL PRIMARY KEY, year_id INTEGER NOT NULL REFERENCES journal_years(id) ON DELETE CASCADE, month INTEGER NOT NULL CHECK (month BETWEEN 1 AND 12), summary_item_id INTEGER NOT NULL REFERENCES journal_summary_items(id) ON DELETE CASCADE, amount NUMERIC(12,2) NOT NULL DEFAULT 0, UNIQUE(year_id, month, summary_item_id) ); -- Indizes für Performance CREATE INDEX IF NOT EXISTS idx_journal_entries_year_month ON journal_entries(year_id, month); CREATE INDEX IF NOT EXISTS idx_journal_entries_date ON journal_entries(entry_date); CREATE INDEX IF NOT EXISTS idx_journal_entry_accounts_entry ON journal_entry_accounts(entry_id); CREATE INDEX IF NOT EXISTS idx_journal_entry_accounts_type ON journal_entry_accounts(account_type);