-- SeCu Partnerships (Subunternehmer-System) -- Version: 1.1.0 -- Partnerschaften zwischen Organisationen CREATE TABLE IF NOT EXISTS org_partnerships ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Hauptunternehmer (der Aufträge vergibt) contractor_org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, -- Subunternehmer (der Mitarbeiter stellt) subcontractor_org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, -- Status der Partnerschaft status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'active', 'paused', 'terminated')), -- Vertragsdetails contract_start DATE, contract_end DATE, notes TEXT, -- Wer hat eingeladen invited_by UUID REFERENCES users(id), accepted_by UUID REFERENCES users(id), accepted_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), -- Ein Subunternehmer kann nur einmal pro Hauptunternehmer existieren UNIQUE(contractor_org_id, subcontractor_org_id), -- Keine Selbst-Partnerschaft CHECK (contractor_org_id != subcontractor_org_id) ); -- Stundensätze und Konditionen pro Partnerschaft CREATE TABLE IF NOT EXISTS partnership_rates ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), partnership_id UUID NOT NULL REFERENCES org_partnerships(id) ON DELETE CASCADE, -- Art des Satzes rate_type VARCHAR(50) NOT NULL DEFAULT 'hourly', -- hourly, daily, fixed, per_order -- Bezeichnung (z.B. "Normaldienst", "Nachtdienst", "Wochenende") name VARCHAR(100) NOT NULL, description TEXT, -- Betrag in Cent (für Genauigkeit) amount_cents INTEGER NOT NULL, currency VARCHAR(3) DEFAULT 'EUR', -- Gültigkeit valid_from DATE DEFAULT CURRENT_DATE, valid_until DATE, -- Standard-Satz? is_default BOOLEAN DEFAULT false, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Geteilte Aufträge (Hauptunternehmer -> Subunternehmer) CREATE TABLE IF NOT EXISTS shared_orders ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), partnership_id UUID NOT NULL REFERENCES org_partnerships(id) ON DELETE CASCADE, -- Original-Auftrag beim Hauptunternehmer original_order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE, -- Kopie/Referenz beim Subunternehmer (optional, wenn sie eigene Aufträge anlegen) sub_order_id UUID REFERENCES orders(id) ON DELETE SET NULL, -- Welcher Satz gilt für diesen Auftrag rate_id UUID REFERENCES partnership_rates(id), -- Anzahl benötigter Mitarbeiter vom Subunternehmer required_staff INTEGER DEFAULT 1, -- Status status VARCHAR(20) NOT NULL DEFAULT 'requested' CHECK (status IN ('requested', 'accepted', 'declined', 'completed', 'cancelled')), -- Notizen zwischen den Unternehmen contractor_notes TEXT, subcontractor_notes TEXT, responded_at TIMESTAMP WITH TIME ZONE, completed_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Stundenzettel von Subunternehmer-Mitarbeitern für geteilte Aufträge CREATE TABLE IF NOT EXISTS partnership_timesheets ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), shared_order_id UUID NOT NULL REFERENCES shared_orders(id) ON DELETE CASCADE, -- Original-Stundenzettel beim Subunternehmer timesheet_id UUID NOT NULL REFERENCES timesheets(id) ON DELETE CASCADE, -- Welcher Satz wurde angewendet rate_id UUID REFERENCES partnership_rates(id), -- Berechneter Betrag calculated_amount_cents INTEGER, -- Status der Freigabe durch Hauptunternehmer approval_status VARCHAR(20) DEFAULT 'pending' CHECK (approval_status IN ('pending', 'approved', 'disputed', 'rejected')), approved_by UUID REFERENCES users(id), approved_at TIMESTAMP WITH TIME ZONE, dispute_reason TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Abrechnungen zwischen Partnern CREATE TABLE IF NOT EXISTS partnership_invoices ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), partnership_id UUID NOT NULL REFERENCES org_partnerships(id) ON DELETE CASCADE, -- Rechnungsnummer invoice_number VARCHAR(50) NOT NULL, -- Abrechnungszeitraum period_start DATE NOT NULL, period_end DATE NOT NULL, -- Beträge subtotal_cents INTEGER NOT NULL DEFAULT 0, tax_percent DECIMAL(5,2) DEFAULT 19.00, tax_cents INTEGER NOT NULL DEFAULT 0, total_cents INTEGER NOT NULL DEFAULT 0, -- Status status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'sent', 'paid', 'overdue', 'cancelled')), -- Daten issued_at TIMESTAMP WITH TIME ZONE, due_date DATE, paid_at TIMESTAMP WITH TIME ZONE, -- PDF-Link (wenn generiert) pdf_url TEXT, -- Notizen notes TEXT, created_by UUID REFERENCES users(id), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Rechnungspositionen CREATE TABLE IF NOT EXISTS partnership_invoice_items ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), invoice_id UUID NOT NULL REFERENCES partnership_invoices(id) ON DELETE CASCADE, -- Referenz zum Stundenzettel (optional) partnership_timesheet_id UUID REFERENCES partnership_timesheets(id), -- Beschreibung description TEXT NOT NULL, -- Mengen und Preise quantity DECIMAL(10,2) NOT NULL DEFAULT 1, unit VARCHAR(20) DEFAULT 'Stunden', unit_price_cents INTEGER NOT NULL, total_cents INTEGER NOT NULL, -- Datum der Leistung service_date DATE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Indexes CREATE INDEX IF NOT EXISTS idx_partnerships_contractor ON org_partnerships(contractor_org_id); CREATE INDEX IF NOT EXISTS idx_partnerships_subcontractor ON org_partnerships(subcontractor_org_id); CREATE INDEX IF NOT EXISTS idx_partnerships_status ON org_partnerships(status); CREATE INDEX IF NOT EXISTS idx_shared_orders_partnership ON shared_orders(partnership_id); CREATE INDEX IF NOT EXISTS idx_shared_orders_original ON shared_orders(original_order_id); CREATE INDEX IF NOT EXISTS idx_partnership_timesheets_shared ON partnership_timesheets(shared_order_id); CREATE INDEX IF NOT EXISTS idx_partnership_invoices_partnership ON partnership_invoices(partnership_id); CREATE INDEX IF NOT EXISTS idx_partnership_invoices_status ON partnership_invoices(status); -- Partnership-Modul registrieren INSERT INTO modules (name, display_name, description, is_core, default_config) VALUES ('partnerships', 'Subunternehmer', 'Zusammenarbeit mit Subunternehmen inkl. Abrechnung', false, '{"auto_approve_timesheets": false, "default_payment_days": 30}') ON CONFLICT (name) DO NOTHING;