p_import_ba_korrespondenz implementiert
This commit is contained in:
@@ -2,56 +2,111 @@ create or replace package body pck_auto_import as
|
||||
|
||||
c_module constant varchar2(20) := 'PCK_AUTO_IMPORT';
|
||||
|
||||
procedure p_import_file (
|
||||
i_object_key in varchar2
|
||||
,i_content in blob
|
||||
procedure p_import_ba_korrespondenz (
|
||||
i_object_key in varchar2
|
||||
,i_content in blob
|
||||
,i_target_folder in varchar2
|
||||
)
|
||||
/*Kopf------------------------------------------------------------------------------------------------
|
||||
-- Beschreibung: Importiert eine einzelne Datei aus dem OCI Eingangsordner in die Datenbank.
|
||||
-- Stub — muss pro Dateityp fachlich implementiert werden.
|
||||
-- Kein Commit hier — wird von p_process_incoming_files übernommen.
|
||||
-- Ruft inkasso.pck_import.f_import_ba_dokument auf.
|
||||
-- Bei Rückgabe 1 (Erfolg): Datei in den Zielordner verschieben.
|
||||
-- Bei Rückgabe != 1 (z.B. ungültiger Dateiname): Warnung loggen und Exception werfen
|
||||
-- — Datei bleibt liegen, Commit/Rollback liegt beim Aufrufer.
|
||||
-- Kein Commit hier — wird von p_process_incoming_ba_data übernommen.
|
||||
------------------------------------------------------------------------------------------------------
|
||||
-- Parameter: i_object_key Vollständiger OCI-Objektkey der zu verarbeitenden Datei
|
||||
-- i_content Dateiinhalt als BLOB
|
||||
-- Parameter: i_object_key Vollständiger OCI-Objektkey der zu verarbeitenden Datei
|
||||
-- i_content Dateiinhalt als BLOB
|
||||
-- i_target_folder Zielordner-Prefix für erfolgreich verarbeitete Dateien
|
||||
------------------------------------------------------------------------------------------------------
|
||||
-- MA Datum Änderung
|
||||
-- SCK 2026-04-08 Stub erstellt
|
||||
-- SCK 2026-04-09 Implementierung: Aufruf f_import_ba_dokument, Wiedervorlage bei Fehler
|
||||
-- SCK 2026-04-09 Move nach erfolgreichem Import in p_import_ba_korrespondenz verschoben
|
||||
------------------------------------------------------------------------------------------------Kopf*/
|
||||
is
|
||||
l_filename varchar2(512);
|
||||
l_file_size number;
|
||||
l_return number;
|
||||
l_log_action varchar2(512 char) := 'IMPORT_BA_PDF_FILE';
|
||||
begin
|
||||
-- TODO: Fachliche Verarbeitung implementieren
|
||||
-- Beispiel: CSV parsen und in Zieltabellen schreiben
|
||||
null;
|
||||
end p_import_file;
|
||||
-- Dateiname aus OCI-Objektkey ableiten (letztes Segment nach '/')
|
||||
l_filename := substr(i_object_key, instr(i_object_key, '/', -1) + 1);
|
||||
l_file_size := dbms_lob.getlength(i_content);
|
||||
|
||||
l_return := inkasso.pck_import.f_import_ba_dokument(
|
||||
i_datei => i_content
|
||||
,i_dateiname => l_filename
|
||||
,i_datei_groesse => l_file_size
|
||||
);
|
||||
|
||||
if l_return != 1
|
||||
then
|
||||
pck_log.p_warn(
|
||||
i_module => c_module
|
||||
,i_action => l_log_action
|
||||
,i_message => 'Import für Datei "' || l_filename || '" fehlgeschlagen (Rückgabe: ' || l_return || ') — Wiedervorlage erforderlich'
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
|
||||
-- Wiedervorlage für Sachbearbeiter erstellen
|
||||
pck_wiedervorlage.p_wiedervorlage_anlegen (i_swv_stp_id_art => pck_stammdaten.f_get_stp_id_by_programmid('WV_IMPORT_DATEV') -- TODO: neue WV Art? z.B. WV_IMPORT_BA_DATEN
|
||||
,i_swv_wdatum => sysdate --TODO: welches Datum? sysdate?
|
||||
,i_swv_bemerkung => 'Bitte manuell Prüfen: Die Datei "' || l_filename || '" konnte nicht automatisch importiert werden (Siehe "' || i_object_key || '").'
|
||||
,i_swv_mit_id_wsachbearbeiter => pck_system.f_get_par_wert_by_programmid('BA_IMPORT_SB_MIT_ID')
|
||||
);
|
||||
|
||||
raise_application_error(-20000, 'Import fehlgeschlagen: "' || l_filename || '" (Rückgabe: ' || l_return || ')');
|
||||
end if;
|
||||
|
||||
-- Datei in Verarbeitet-Ordner verschieben
|
||||
pck_net_storage.p_move_object(
|
||||
i_object_key => i_object_key
|
||||
,i_target_prefix => i_target_folder
|
||||
);
|
||||
|
||||
pck_log.p_info(
|
||||
i_module => c_module
|
||||
,i_action => l_log_action
|
||||
,i_message => 'Datei "' || l_filename || '" erfolgreich verarbeitet und verschoben'
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
end p_import_ba_korrespondenz;
|
||||
|
||||
procedure p_process_incoming_ba_data
|
||||
/*Kopf------------------------------------------------------------------------------------------------
|
||||
-- Beschreibung: Verarbeitet alle fertigen Eingangs-Batches aus dem OCI Eingangsordner.
|
||||
-- Wird von ORDS-Endpunkt und APEX Automation aufgerufen.
|
||||
-- Pro Datei: Import → Move → Commit (Rollback + Fehlereintrag bei Exception).
|
||||
-- Marker wird gelöscht wenn keine Dateien mehr im Unterordner verbleiben.
|
||||
-- Pro Datei: Import + Move → Commit; bei Exception: Rollback, Datei bleibt liegen,
|
||||
-- nächste Datei wird trotzdem verarbeitet.
|
||||
-- Nach dem Datei-Loop: DB-Marker immer löschen (verhindert erneuten Durchlauf).
|
||||
-- Wenn danach noch Dateien im Ordner liegen: SB-Marker anlegen damit Sachbearbeiter
|
||||
-- die übriggebliebenen Dateien manuell prüfen können.
|
||||
------------------------------------------------------------------------------------------------------
|
||||
-- MA Datum Änderung
|
||||
-- SCK 2026-04-08 Prozedur erstellt
|
||||
-- SCK 2026-04-09 Fehlerbehandlung: Datei bleibt liegen, Fehler-Marker, kein erneuter Durchlauf
|
||||
-- SCK 2026-04-09 SB-Marker statt l_had_errors-Flag; Move in p_import_ba_korrespondenz verschoben
|
||||
------------------------------------------------------------------------------------------------Kopf*/
|
||||
is
|
||||
l_marker_key varchar2(1024);
|
||||
l_target_folder varchar2(4000 char);
|
||||
l_target_prefix varchar2(4000 char);
|
||||
l_eingang_prefix varchar2(4000 char);
|
||||
l_zip_name varchar2(512);
|
||||
l_file_content blob;
|
||||
l_meta pck_net_storage.t_object_meta;
|
||||
l_remaining number;
|
||||
l_folders t_net_storage_tab;
|
||||
l_files t_net_storage_tab;
|
||||
l_check t_net_storage_tab;
|
||||
l_db_processing_marker_key varchar2(1024);
|
||||
l_sb_marker_key varchar2(1024);
|
||||
l_target_folder varchar2(4000 char);
|
||||
l_target_prefix varchar2(4000 char);
|
||||
l_eingang_prefix varchar2(4000 char);
|
||||
l_zip_name varchar2(512);
|
||||
l_file_content blob;
|
||||
l_meta pck_net_storage.t_object_meta;
|
||||
l_folders t_net_storage_tab;
|
||||
l_files t_net_storage_tab;
|
||||
l_has_remaining_files boolean;
|
||||
l_log_action varchar2(512 char) := 'IMPORT_BA_DATA';
|
||||
begin
|
||||
-- Zielordner Name zusammenstellen
|
||||
l_target_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_PREFIX') || 'Verarbeitet ' || to_char(sysdate, 'YYYY') || '/';
|
||||
l_eingang_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_PREFIX') || pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_IMPORT');
|
||||
|
||||
-- Unterordner in eingang/ auflisten (Delimiter '/' liefert nur direkte Kinder)
|
||||
-- Unterordner in eingangs-ordner auflisten (es gibt einen Ordner für jeden entpackte ZIP-Datei) (Delimiter '/' liefert nur direkte Kinder)
|
||||
l_folders := pck_net_storage.f_list_objects(
|
||||
i_prefix => l_eingang_prefix
|
||||
,i_delimiter => '/'
|
||||
@@ -67,11 +122,11 @@ create or replace package body pck_auto_import as
|
||||
|
||||
-- Der Marker ist eine Datei mit speziellem Namen, welche vom quarkus automaton in einen entpackten zip-ordner gelegt wird um zu signalisieren, dass alle Dateien des ZIPs erfolgreich in den ordner gelegt wurden.
|
||||
-- Das verhindert die verarbeitung von unvollständig entpackten zips
|
||||
l_marker_key := rec_folder.object_name || pck_system.f_get_par_wert_by_programmid('NETSTORE_MARKER_NAME');
|
||||
l_db_processing_marker_key := rec_folder.object_name || pck_system.f_get_par_wert_by_programmid('NETSTORE_MARKER_DB');
|
||||
|
||||
-- Marker prüfen: -20001 = nicht vorhanden → Upload noch nicht abgeschlossen
|
||||
begin
|
||||
l_meta := pck_net_storage.f_get_object_metadata(l_marker_key);
|
||||
l_meta := pck_net_storage.f_get_object_metadata(l_db_processing_marker_key);
|
||||
exception
|
||||
when others
|
||||
then
|
||||
@@ -99,7 +154,7 @@ create or replace package body pck_auto_import as
|
||||
for rec_file in (select object_name, is_folder from table(l_files))
|
||||
loop
|
||||
-- Marker und Pseudo-Ordner überspringen
|
||||
if rec_file.object_name = l_marker_key or rec_file.is_folder = 'Y'
|
||||
if rec_file.object_name = l_db_processing_marker_key or rec_file.is_folder = 'Y'
|
||||
then
|
||||
continue;
|
||||
end if;
|
||||
@@ -108,24 +163,13 @@ create or replace package body pck_auto_import as
|
||||
-- 1. Dateiinhalt laden
|
||||
l_file_content := pck_net_storage.f_download_object(rec_file.object_name);
|
||||
|
||||
-- 2. Fachliche Verarbeitung (noch kein Commit)
|
||||
p_import_file(rec_file.object_name, l_file_content);
|
||||
|
||||
-- 3. Datei in Zielordner verschieben (noch kein Commit)
|
||||
-- Rollback von p_move_object macht auch den Import rückgängig
|
||||
pck_net_storage.p_move_object(
|
||||
i_object_key => rec_file.object_name
|
||||
,i_target_prefix => l_target_folder
|
||||
);
|
||||
-- 2. Fachliche Verarbeitung + Move bei Erfolg (innerhalb p_import_ba_korrespondenz)
|
||||
p_import_ba_korrespondenz(rec_file.object_name, l_file_content, l_target_folder);
|
||||
|
||||
-- Commit pro Datei: OCI-Move ist nicht transaktional, daher DB-Änderungen sofort sichern
|
||||
-- sonst würde ein Fehler bei einer späteren Datei den DB-Import bereits verschobener Dateien zurückrollen
|
||||
commit;
|
||||
|
||||
pck_log.p_info(
|
||||
i_module => c_module
|
||||
,i_action => 'IMPORT_FILE'
|
||||
,i_message => 'Datei erfolgreich verarbeitet'
|
||||
,i_object_ref => rec_file.object_name
|
||||
);
|
||||
exception
|
||||
when others
|
||||
then
|
||||
@@ -140,31 +184,46 @@ create or replace package body pck_auto_import as
|
||||
end;
|
||||
end loop;
|
||||
|
||||
-- Prüfen ob noch nicht verarbeitete Dateien im Unterordner verbleiben
|
||||
l_remaining := 0;
|
||||
-- DB-Marker immer entfernen — verhindert erneute Verarbeitung beim nächsten Lauf
|
||||
pck_net_storage.p_delete_object(l_db_processing_marker_key);
|
||||
|
||||
l_check := pck_net_storage.f_list_objects(
|
||||
-- Prüfen ob noch Dateien im Unterordner liegen (nicht erfolgreich importierte Dateien)
|
||||
l_files := pck_net_storage.f_list_objects(
|
||||
i_prefix => rec_folder.object_name
|
||||
,i_delimiter => ''
|
||||
);
|
||||
|
||||
for rec_check in (select object_name, is_folder from table(l_check))
|
||||
l_has_remaining_files := false;
|
||||
|
||||
for rec_remaining in (select object_name, is_folder from table(l_files))
|
||||
loop
|
||||
if rec_check.object_name != l_marker_key and rec_check.is_folder = 'N'
|
||||
if rec_remaining.is_folder != 'Y'
|
||||
then
|
||||
l_remaining := l_remaining + 1;
|
||||
l_has_remaining_files := true;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
-- Marker löschen wenn Batch vollständig abgeschlossen
|
||||
if l_remaining = 0
|
||||
if l_has_remaining_files
|
||||
then
|
||||
pck_net_storage.p_delete_object(l_marker_key);
|
||||
|
||||
-- SB-Marker anlegen: signalisiert Sachbearbeitern, dass Dateien manuell geprüft werden müssen
|
||||
l_sb_marker_key := rec_folder.object_name || pck_system.f_get_par_wert_by_programmid('NETSTORE_MARKER_SB');
|
||||
pck_net_storage.p_upload_object(
|
||||
i_object_key => l_sb_marker_key
|
||||
,i_content => empty_blob()
|
||||
,i_content_type => 'application/octet-stream'
|
||||
);
|
||||
pck_log.p_warn(
|
||||
i_module => c_module
|
||||
,i_action => l_log_action
|
||||
,i_message => 'Batch mit Fehlern abgeschlossen — mind. eine Datei konnte nicht importiert werden, SB-Marker gesetzt'
|
||||
,i_object_ref => rec_folder.object_name
|
||||
);
|
||||
else
|
||||
pck_log.p_info(
|
||||
i_module => c_module
|
||||
,i_action => 'PROCESS_INCOMING'
|
||||
,i_message => 'Batch abgeschlossen, Marker gelöscht'
|
||||
,i_action => l_log_action
|
||||
,i_message => 'Batch abgeschlossen, alle Dateien erfolgreich importiert'
|
||||
,i_object_ref => rec_folder.object_name
|
||||
);
|
||||
end if;
|
||||
|
||||
Reference in New Issue
Block a user