Files
Dokumenten-Check/Scripts/DC_UTILS_PKG.sql
Wolf G. Beckmann ac9ab7ab15 feat: Add catalog generation functionality and related models
- Implemented CatalogResource for handling catalog generation requests and status checks.
- Created CatalogGenerationService to manage the asynchronous generation process.
- Added models for catalog generation responses, requests, and structured catalog data.
- Introduced utility scripts for database interaction and Kubernetes pod retrieval.
- Enhanced error handling and logging throughout the catalog generation workflow.
2026-05-04 19:03:54 +02:00

232 lines
8.1 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================================================
-- DC_UTILS_PKG
-- Hilfsprozeduren und -funktionen für den Dokumenten-Check
--
-- Deployment:
-- sqlplus user/pass@db @"Scripts/DC_UTILS_PKG.sql"
-- =============================================================================
-- =============================================================================
-- Package Spec
-- =============================================================================
CREATE OR REPLACE PACKAGE DC_UTILS_PKG AS
-- -------------------------------------------------------------------------
-- Erstellt einen Markdown-Prüfbericht für ein Projekt und speichert ihn
-- in dc_projects.report_markdown.
--
-- Aufbau des Berichts:
-- 1. Kopf (Projektname, Abschlussdatum)
-- 2. Zusammenfassung (OK / Hinweise / Abweichungen)
-- 3. Ergebnisse: je Dokument → Kategorie (order_nr) → Frage (order_nr)
-- Icons: ✅ OK | ⚠️ Hinweis | ❌ Abweichung | ❓ Unklar
--
-- Beispiel:
-- BEGIN DC_UTILS_PKG.generate_report(p_project_id => 1); COMMIT; END;
-- -------------------------------------------------------------------------
PROCEDURE generate_report(p_project_id IN NUMBER);
END DC_UTILS_PKG;
/
-- =============================================================================
-- Package Body
-- =============================================================================
CREATE OR REPLACE PACKAGE BODY DC_UTILS_PKG AS
-- -------------------------------------------------------------------------
PROCEDURE generate_report(p_project_id IN NUMBER) IS
v_md CLOB;
v_name dc_projects.name%TYPE;
v_status dc_projects.status%TYPE;
v_done dc_projects.completed_at%TYPE;
v_ok_cnt NUMBER := 0;
v_warn_cnt NUMBER := 0;
v_dev_cnt NUMBER := 0;
v_unkl_cnt NUMBER := 0;
v_total NUMBER := 0;
-- Emoji-Konstanten via UNISTR (vermeidet Quellcode-Encoding-Probleme)
C_OK CONSTANT VARCHAR2(10 CHAR) := UNISTR('\2705'); -- ✅
C_NOK CONSTANT VARCHAR2(10 CHAR) := UNISTR('\274C'); -- ❌
C_WARN CONSTANT VARCHAR2(10 CHAR) := UNISTR('\26A0\FE0F'); -- ⚠️
C_UNKL CONSTANT VARCHAR2(10 CHAR) := UNISTR('\2753'); -- ❓
C_DOC CONSTANT VARCHAR2(10 CHAR) := UNISTR('\D83D\DCC4'); -- 📄
CURSOR c_docs IS
SELECT d.id, d.filename
FROM dc_project_documents d
WHERE d.project_id = p_project_id
ORDER BY d.uploaded_at, d.id;
CURSOR c_cats(p_doc_id NUMBER) IS
SELECT DISTINCT qc.id, qc.name, qc.order_nr
FROM dc_question_categories qc
JOIN dc_questions q ON q.category_id = qc.id
JOIN dc_results r ON r.question_id = q.id
WHERE r.project_id = p_project_id
AND r.doc_id = p_doc_id
ORDER BY qc.order_nr, qc.name;
CURSOR c_qs(p_doc_id NUMBER, p_cat_id NUMBER) IS
SELECT q.question_text,
r.result_type,
r.score,
r.deviation,
r.warning,
r.answer,
r.the_comment
FROM dc_questions q
JOIN dc_results r ON r.question_id = q.id
WHERE r.project_id = p_project_id
AND r.doc_id = p_doc_id
AND q.category_id = p_cat_id
ORDER BY q.order_nr, q.id;
v_icon VARCHAR2(20 CHAR);
-- Fügt eine Zeile + Newline an den CLOB an. Akzeptiert CLOB damit kein
-- implizites CLOB→VARCHAR2-Cast nötig ist (question_text etc. sind CLOBs).
PROCEDURE ln(p_text IN CLOB DEFAULT NULL) IS
BEGIN
IF p_text IS NOT NULL AND DBMS_LOB.GETLENGTH(p_text) > 0 THEN
DBMS_LOB.APPEND(v_md, p_text);
END IF;
DBMS_LOB.APPEND(v_md, TO_CLOB(CHR(13)||CHR(10)));
END ln;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_md, TRUE);
SELECT name, status, completed_at
INTO v_name, v_status, v_done
FROM dc_projects
WHERE id = p_project_id;
SELECT SUM(CASE WHEN deviation = 1 THEN 1 ELSE 0 END),
SUM(CASE WHEN warning = 1 THEN 1 ELSE 0 END),
SUM(CASE WHEN result_type = 'UNKLAR'
AND deviation = 0
AND warning = 0 THEN 1 ELSE 0 END),
COUNT(*)
INTO v_dev_cnt, v_warn_cnt, v_unkl_cnt, v_total
FROM dc_results
WHERE project_id = p_project_id;
v_ok_cnt := v_total - v_dev_cnt - v_warn_cnt - v_unkl_cnt;
-- =====================================================================
-- Kopf
-- =====================================================================
ln('# Prüfbericht: ' || v_name);
ln();
IF v_done IS NOT NULL THEN
ln('**Abgeschlossen:** ' || TO_CHAR(v_done, 'DD.MM.YYYY HH24:MI'));
ELSE
ln('**Erstellt:** ' || TO_CHAR(SYSDATE, 'DD.MM.YYYY HH24:MI'));
END IF;
ln();
ln('---');
ln();
-- =====================================================================
-- Zusammenfassung (keine Tabelle Plaintext für maximale Kompatibilität)
-- =====================================================================
ln('## Zusammenfassung');
ln();
ln(C_OK || ' OK: ' || v_ok_cnt);
ln(C_WARN || ' Hinweise: ' || v_warn_cnt);
ln(C_NOK || ' Abweichungen: ' || v_dev_cnt);
IF v_unkl_cnt > 0 THEN
ln(C_UNKL || ' Unklar: ' || v_unkl_cnt);
END IF;
ln('**Gesamt: ' || v_total || '**');
ln();
ln('---');
ln();
-- =====================================================================
-- Ergebnisse je Dokument → Kategorie (order_nr) → Frage (order_nr)
-- =====================================================================
ln('## Ergebnisse');
ln();
FOR doc IN c_docs LOOP
ln('## ' || C_DOC || ' ' || doc.filename);
ln();
FOR cat IN c_cats(doc.id) LOOP
ln();
ln('### ' || cat.name);
ln();
FOR q IN c_qs(doc.id, cat.id) LOOP
IF q.deviation = 1 THEN v_icon := C_NOK;
ELSIF q.warning = 1 THEN v_icon := C_WARN;
ELSIF q.result_type = 'UNKLAR' THEN v_icon := C_UNKL;
ELSE v_icon := C_OK;
END IF;
ln();
ln();
ln(v_icon || ' **' || q.question_text || '**');
ln();
IF q.answer IS NOT NULL AND DBMS_LOB.GETLENGTH(q.answer) > 0 THEN
ln(q.answer);
ln();
END IF;
IF q.score IS NOT NULL THEN
ln('*Score: ' || q.score || '%*');
END IF;
IF q.the_comment IS NOT NULL
AND DBMS_LOB.GETLENGTH(q.the_comment) > 0 THEN
ln();
ln('> ' || q.the_comment);
END IF;
ln();
END LOOP;
END LOOP;
ln('---');
ln();
END LOOP;
UPDATE dc_projects
SET report_markdown = v_md
WHERE id = p_project_id;
DBMS_LOB.FREETEMPORARY(v_md);
EXCEPTION
WHEN OTHERS THEN
DBMS_LOB.FREETEMPORARY(v_md);
RAISE;
END generate_report;
END DC_UTILS_PKG;
/
-- =============================================================================
-- Schnelltest (optional, auskommentiert)
-- =============================================================================
/*
BEGIN
DC_UTILS_PKG.generate_report(p_project_id => 1);
COMMIT;
DBMS_OUTPUT.PUT_LINE('Bericht generiert.');
END;
/
*/