-- Справочник статей расходов -- Категории расходов CREATE TABLE IF NOT EXISTS expense_categories ( id BIGSERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE, code VARCHAR(50) UNIQUE, -- Код категории (опционально) description TEXT, sort_order INTEGER DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Статьи расходов внутри категорий CREATE TABLE IF NOT EXISTS expense_items ( id BIGSERIAL PRIMARY KEY, category_id BIGINT NOT NULL REFERENCES expense_categories(id) ON DELETE CASCADE, name TEXT NOT NULL, code VARCHAR(50), -- Код статьи (опционально) description TEXT, parent_item_id BIGINT REFERENCES expense_items(id) ON DELETE CASCADE, -- Для вложенных статей sort_order INTEGER DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(category_id, name) ); -- Индексы CREATE INDEX IF NOT EXISTS idx_expense_items_category ON expense_items(category_id); CREATE INDEX IF NOT EXISTS idx_expense_items_parent ON expense_items(parent_item_id); CREATE INDEX IF NOT EXISTS idx_expense_items_active ON expense_items(is_active); CREATE INDEX IF NOT EXISTS idx_expense_categories_active ON expense_categories(is_active); -- Связь данных отчета со справочником -- Добавляем поле для хранения ID статьи из справочника ALTER TABLE building_financial_data ADD COLUMN IF NOT EXISTS expense_item_mappings JSONB DEFAULT '{}'; COMMENT ON TABLE expense_categories IS 'Справочник категорий расходов'; COMMENT ON TABLE expense_items IS 'Справочник статей расходов внутри категорий'; COMMENT ON COLUMN building_financial_data.expense_item_mappings IS 'Маппинг расходов на статьи из справочника: { "item_id": amount, ... }';