From 4ece42825ef42b41189e55948f6f091f0faf0b8c Mon Sep 17 00:00:00 2001 From: Simon Steuer Date: Tue, 2 Sep 2025 15:45:47 +0200 Subject: [PATCH] =?UTF-8?q?Finalen=20Stand=20des=20Workflow=2096=20(Stand?= =?UTF-8?q?=20250902)=20von=20Hr.=20Jakob=20erg=C3=A4nzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Implementation_Workflow96_JIT.pck | 4150 +++++++++++++++++++++++++ 1 file changed, 4150 insertions(+) create mode 100644 lib/Implementation_Workflow96_JIT.pck diff --git a/lib/Implementation_Workflow96_JIT.pck b/lib/Implementation_Workflow96_JIT.pck new file mode 100644 index 0000000..627e0fd --- /dev/null +++ b/lib/Implementation_Workflow96_JIT.pck @@ -0,0 +1,4150 @@ +create or replace package k_ruledesigner is + +procedure import(i_protok in varchar default 'N'); +function import_parts(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean; +function import_comp_alt(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean; + +function import_comp(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean; + +function import_parts_aend_dokumente(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean; + +function rd_to_number(i_numeric_string in varchar2) return number; + +function rd_user_to_sivas(i_rd_user in varchar2) return varchar2; + +procedure index_klein_zu_gross; + +procedure sik_schreiben(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type); + +procedure sik_loeschen(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type); + +function comp_hist_rb_vorh_jn(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2; + +function comp_hist_dispo_jn(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2; + +function comp_hist_zuschnitt(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return number; + +function comp_hist_ruestcode(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2; + +end; +/ +create or replace package body k_ruledesigner is + + g_lfdnr_rb_vorh_ja klas_auspraegung.lfd_nr%type := 2510; + g_lfdnr_rb_vorh_nein klas_auspraegung.lfd_nr%type := 2511; + g_lfdnr_dispo_ja klas_auspraegung.lfd_nr%type := 2513; + g_lfdnr_dispo_nein klas_auspraegung.lfd_nr%type := 2514; + g_lfdnr_zuschnitt klas_auspraegung.lfd_nr%type := 2515; + g_lfdnr_ruestcode klas_auspraegung.lfd_nr%type := 2516; + +--------------------------------------------------------------------------------- + +function rd_protok_init return k_ruledesigner_protok%rowtype is + xx_rd_protok k_ruledesigner_protok%rowtype; +begin + xx_rd_protok.lfd_nr := null; + xx_rd_protok.erfass_datum := sysdate; + xx_rd_protok.erledigt_datum := null; + xx_rd_protok.meldung := null; + xx_rd_protok.fehler_jn := null; + return xx_rd_protok; +end; + +--------------------------------------------------------------------------------- + +procedure rd_protok(i_kontext in sivas_aj.k_ruledesigner_konfig.kontext%type, + i_pfad in file_beschreibung.file_pfad%type, + i_meldung in k_ruledesigner_protok.meldung%type default null, + i_fehler_jn in k_ruledesigner_protok.fehler_jn%type default null, + i_meldung_av in k_ruledesigner_protok.meldung_av%type default null, + i_meldung_tos in k_ruledesigner_protok.meldung_tos%type default null, + i_meldung_beist in k_ruledesigner_protok.meldung_beist%type default null) is + + pragma autonomous_transaction; + + xx_rd_protok k_ruledesigner_protok%rowtype := rd_protok_init; +begin + xx_rd_protok.kontext := i_kontext; + xx_rd_protok.pfad := i_pfad; + xx_rd_protok.meldung := i_meldung; + xx_rd_protok.meldung_av := i_meldung_av; + xx_rd_protok.meldung_tos := i_meldung_tos; + xx_rd_protok.meldung_beist := i_meldung_beist; + xx_rd_protok.erledigt_datum := sysdate; + xx_rd_protok.fehler_jn := i_fehler_jn; + insert into k_ruledesigner_protok values xx_rd_protok; + commit; +end; + +--------------------------------------------------------------------------------- + +procedure rd_protok_fehler(i_kontext in sivas_aj.k_ruledesigner_konfig.kontext%type, + i_pfad in file_beschreibung.file_pfad%type, + i_meldung in k_ruledesigner_protok.meldung%type, + i_meldung_av in k_ruledesigner_protok.meldung_av%type default null, + i_meldung_tos in k_ruledesigner_protok.meldung_tos%type default null, + i_meldung_beist in k_ruledesigner_protok.meldung_beist%type default null) is +begin + rd_protok(i_kontext => i_kontext, + i_pfad => i_pfad, + i_meldung => i_meldung, + i_meldung_av => i_meldung_av, + i_meldung_tos => i_meldung_tos, + i_meldung_beist => i_meldung_beist, + i_fehler_jn => 'J'); +end; + + +--------------------------------------------------------------------------------- + +procedure import(i_protok in varchar default 'N') is + + cursor c_rd_konfig is + select kontext, + verzeichnis + from sivas_aj.k_ruledesigner_konfig + order by reihenfolge; + + cursor c_datei(ic_verzeichnis sivas_aj.k_ruledesigner_konfig.verzeichnis%type) is + select substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1) datei_name, + f.pfad_datei voller_pfad, + lower(substr(f.pfad_datei, instr(f.pfad_datei, '.', -1)+1)) ext, + substr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), 1, instr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), '-')-1) teilenr, + substr(upper(substr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), instr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), '-')+1)), 1, instr(upper(substr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), instr(substr(f.pfad_datei, instr(f.pfad_datei, '/', -1)+1), '-')+1)), '.', -1)-1) aend_index + from filesystem_verzeichnis f + where nvl(verzeichnis_jn, 'N') = 'N' + and f.pfad_datei like ic_verzeichnis || '%' + and lower(substr(f.pfad_datei, instr(f.pfad_datei, '.', -1)+1)) in ('csv', 'pdf', 'dwg', 'stp'); + + cursor c_mv_error_vorh(ic_kontext varchar2, + ic_pfad varchar2) is + select 1 + from k_ruledesigner_protok + where pfad = ic_pfad + and kontext = ic_kontext + and meldung like 'Fehler beim Verschieben der Datei%' + and (sysdate - erfass_datum) * 24 < 1; + x_num number; + + x_plsql varchar2(4000); + -- x_voller_pfad varchar2(4000); + x_meldung varchar2(4000); + x_ok number; + + x_datei_name varchar2(500); + x_quell_pfad varchar2(3000); + x_ziel_pfad varchar2(3000); + x_ziel_verzeichnis varchar2(2000); + + x_erg_edm number; + x_verzeichnis_edm varchar2(4000); + + x_pfad_substr varchar2(100); + x_fehler boolean; + +BEGIN +/* if not allgemein.pruefe_instanz('LINUX') then + return; + end if;*/ + + if lower(sys_context('userenv','instance_name')) like '%schul%' then + x_pfad_substr := 'Schulung/'; + else + x_pfad_substr := null; + end if; + + protok('k_ruledesigner.import - start', i_protok); + + for xx_rd_konfig in c_rd_konfig loop + + protok('k_ruledesigner.import - 1 - verzeichnis: ' || xx_rd_konfig.verzeichnis, i_protok); + + delete from filesystem_verzeichnis; + + verzeichnis_auslesen(idir => xx_rd_konfig.verzeichnis); + + protok('k_ruledesigner.import - 2 - verzeichnis: ' || xx_rd_konfig.verzeichnis, i_protok); + + for xx_datei in c_datei(xx_rd_konfig.verzeichnis) loop + x_fehler := false; + protok('k_ruledesigner.import - 3 - verzeichnis: ' || xx_rd_konfig.verzeichnis || ', voller_pfad: ' || xx_datei.voller_pfad, i_protok); + + x_datei_name := substr(xx_datei.voller_pfad, instr(xx_datei.voller_pfad, '/', -1)+1); + if upper(xx_rd_konfig.kontext) = 'PARTS_AEND_DOKUMENTE' then + x_ziel_pfad := '/u/sivas/ruledesigner/' || x_pfad_substr || 'Archiv/' || xx_datei.teilenr || '/' || xx_datei.aend_index || '/' || x_datei_name; + else + x_ziel_pfad := xx_datei.voller_pfad; + end if; + + x_plsql := 'begin if sivas_aj.k_ruledesigner.import_' || xx_rd_konfig.kontext || ' (:1, :2, :3) then :4 := 1; else :4 := 0; end if; end;'; + execute immediate x_plsql using x_ziel_pfad, out x_meldung, i_protok, out x_ok; + + protok('k_ruledesigner.import - 4 - verzeichnis: ' || xx_rd_konfig.verzeichnis || ', voller_pfad: ' || xx_datei.voller_pfad, i_protok); + + if xx_datei.ext in ('pdf', 'dwg', 'stp') then + x_quell_pfad := xx_datei.voller_pfad; + else + x_quell_pfad := xx_rd_konfig.verzeichnis || '/work/' || x_datei_name; + end if; + + if x_ok = 0 and x_meldung is not null then + rd_protok_fehler(i_kontext => xx_rd_konfig.kontext, + i_pfad => xx_datei.voller_pfad, + i_meldung => x_meldung); + x_ziel_verzeichnis := xx_rd_konfig.verzeichnis || '/error/'; + x_fehler := true; + else + if xx_datei.ext = 'csv' then + x_ziel_verzeichnis := xx_rd_konfig.verzeichnis || '/done/'; + elsif xx_datei.ext in ('pdf', 'stp', 'dwg') then + x_erg_edm := 0; + x_ziel_verzeichnis := '/u/sivas/ruledesigner/' || x_pfad_substr || 'Archiv/' || xx_datei.teilenr; + x_erg_edm := edm.verzeichnis_vorhanden(x_ziel_verzeichnis, x_verzeichnis_edm); + if x_erg_edm != 0 then + x_erg_edm := 0; + x_erg_edm := edm.verzeichnis_anlegen(x_ziel_verzeichnis, x_verzeichnis_edm); + if x_erg_edm != 0 then + -- Fehler? + null; + end if; + end if; + + x_erg_edm := 0; + x_ziel_verzeichnis := '/u/sivas/ruledesigner/' || x_pfad_substr || 'Archiv/' || xx_datei.teilenr || '/' || xx_datei.aend_index; + x_erg_edm := edm.verzeichnis_vorhanden(x_ziel_verzeichnis, x_verzeichnis_edm); + if x_erg_edm != 0 then + x_erg_edm := 0; + x_erg_edm := edm.verzeichnis_anlegen(x_ziel_verzeichnis, x_verzeichnis_edm); + if x_erg_edm != 0 then + -- Fehler? + null; + end if; + end if; + x_ziel_verzeichnis := x_ziel_verzeichnis || '/'; + end if; + end if; + + protok('k_ruledesigner.import - 5 - verzeichnis: ' || xx_rd_konfig.verzeichnis || ', voller_pfad: ' || xx_datei.voller_pfad, i_protok); + + -- Datei verschieben + if edm.bs_loeschen(x_ziel_verzeichnis || x_datei_name) is null then + null; + end if; + + if edm.bs_verschieben(x_quell_pfad || ' ' || x_ziel_verzeichnis || x_datei_name) != '0' then + -- Fehler + open c_mv_error_vorh(xx_rd_konfig.kontext, xx_datei.voller_pfad); + fetch c_mv_error_vorh into x_num; + if c_mv_error_vorh%notfound then + rd_protok_fehler(i_kontext => xx_rd_konfig.kontext, + i_pfad => xx_datei.voller_pfad, + i_meldung => 'Fehler beim Verschieben der Datei von ' || x_quell_pfad || ' nach ' || x_ziel_verzeichnis || x_datei_name || '.'); + end if; + close c_mv_error_vorh; + elsif not x_fehler then + rd_protok(i_kontext => xx_rd_konfig.kontext, + i_pfad => xx_datei.voller_pfad, + i_meldung => x_meldung); + end if; + + protok('k_ruledesigner.import - 6 - verzeichnis: ' || xx_rd_konfig.verzeichnis || ', voller_pfad: ' || xx_datei.voller_pfad, i_protok); + + -- x_text := edm.bs_verschieben(i_optionen => xx_datei.pfad_datei || ' /u/sivas/schnittstelle/seeger/schon_vorhanden/' || xx_datei.name); + end loop; + end loop; + + delete from sivas.k_ruledesigner_protok r + where r.erfass_datum < sysdate - 30 + and r.erledigt_datum is not null; + + protok('k_ruledesigner.import - ende', i_protok); +end; + +-------------------------------------------------------------------------------------------- + + +function import_parts(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean is + x_datei_name varchar2(500) := substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1); + x_verzeichnis varchar2(2000) := substr(i_voller_pfad, 1, instr(i_voller_pfad, '/', -1)); + x_work_dir varchar2(2000) := x_verzeichnis || 'work/'; + + x_file utl_file.file_type; + x_zeile varchar2(32000); + x_text varchar2(32000); + x_header_zeile boolean := true; + + xx_parts parts%rowtype := null; + xx_grnr_text grnr_text%rowtype := null; + xx_parts_aend parts_aend%rowtype := null; + xx_parts_aend_text parts_aend_text%rowtype := null; + + x_anz_spalten number := 30; + x_spalte number := 1; + x_spalte_teilenr number := 1; + x_spalte_bez number := 2; + x_spalte_ersteller number := 3; + x_spalte_aenderer number := 4; + x_spalte_index number := 5; + x_spalte_kzkauf number := 6; + x_spalte_grnr number := 7; + x_spalte_dispogr number := 8; + x_spalte_dispolauf number := 9; + x_spalte_mengenc number := 10; + x_spalte_ersetzt_teil number := 11; + x_spalte_ersetz_durch number := 12; + x_spalte_werkstoff number := 13; + x_spalte_oberflaeche number := 14; + x_spalte_farbe number := 15; + x_spalte_alternativ_werkstoff number := 16; + x_spalte_alternaiv_farbe number := 17; + x_spalte_fertigungsart number := 18; + x_spalte_fos_gruppe number := 19; + x_spalte_aend_text number := 20; + x_spalte_freigabe_text number := 21; + x_spalte_halbzeug_jn number := 22; + x_spalte_bez_halbzeug number := 23; + x_spalte_hz_ohne_saegeliste number := 24; + x_spalte_hersteller number := 25; + x_spalte_hersteler_teilenr number := 26; + x_spalte_kalkart number := 27; + x_spalte_ruestcode number := 28; + x_spalte_serienstatus number := 29; + x_spalte_kategorie number := 30; + + x_alternativ_werkstoff grnr_text.text%type; + x_alternativ_farbe grnr_text.text%type; + x_erfasser_neu parts.erfass_user%type; + x_kzkauf_neu parts.kzkauf%type; + x_grnr_neu parts.grnr%type; + x_dispo_gruppe_neu parts.dispo_gruppe%type; + x_dispolauf_gruppe_neu parts.dispolauf_gruppe%type; + x_mengenc_neu parts.mengenc%type; + x_farbe_neu teil_merk.text%type; + x_alternativwerkstoff_neu grnr_text.text%type; + x_alternativfarbe_neu grnr_text.text%type; + x_fertigungsart_neu parts.c_teil_art%type; + x_fos_grnr_neu parts.fos_grnr%type; + x_abw_anzahl_jn_neu parts.abw_anzahl_jn%type; + x_hz_ohne_saegeliste_neu parts.info2_jn%type; + x_hersteller_neu parts.hersteller%type; + x_kdnr_hersteller_neu parts.kdnr_hersteller%type; + x_teilenr_hersteller_neu parts.teilenr_hersteller%type; + x_kalkart_neu parts.info14%type; + x_ruestcode_neu parts.ruestcode%type; + x_serien_status varchar2(100); + x_kategorie varchar2(100); + + cursor c_werte(ic_zeile varchar) is + select lvl, + replace(regexp_substr(ic_zeile, '[^;]*;?', 1, lvl), ';') wert, + count(*) over () anz + from dual cross apply (select level lvl + from dual + connect by level <= regexp_count(ic_zeile, ';') + 1); + + cursor c_parts_exists(ic_teilenr parts.teilenr%type) is + select bez + from parts + where teilenr = ic_teilenr; + x_parts_exists parts.bez%type; + + cursor c_grnr_exists(ic_grnr parts.grnr%type) is + select g.grnr + from grpfamsp g + where g.grnr = ic_grnr; + x_grnr_exists grpfamsp.grnr%type; + + cursor c_dispogr_exists(ic_dispo_gruppe parts.dispo_gruppe%type) is + select d.dispo_gruppe + from dispogr d + where d.dispo_gruppe = ic_dispo_gruppe; + x_dispogr_exists dispogr.dispo_gruppe%type; + + cursor c_dispolaufgruppe_exists(ic_dispolaufgruppe parts.dispolauf_gruppe%type) is + select d.dispolauf_gruppe + from dispolauf_gruppen d + where d.dispolauf_gruppe = ic_dispolaufgruppe; + x_dispolaufgruppe_exists dispolauf_gruppen.dispolauf_gruppe%type; + + cursor c_mengeneinheit_exists(ic_mengeneinheit parts.mengenc%type) is + select d.mengenc + from mengeneinheiten d + where d.mengenc = ic_mengeneinheit; + x_mengeneinheit_exists mengeneinheiten.mengenc%type; + + cursor c_werkstoff_exists(ic_werkstoff parts.werkstoff%type) is + select text + from merkinh + where sprache = 'D' + and leisten_nr = 2 + and text = ic_werkstoff; + x_werkstoff_exists merkinh.text%type; + + cursor c_fertigungsteil_exists(ic_fertigungsteil c_teil_art.c_teil_art%type) is + select c_teil_art + from c_teil_art + where c_teil_art = ic_fertigungsteil; + x_fertigungsteil_exists c_teil_art.c_teil_art%type; + + cursor c_teilefarbe_exists(ic_farbe teil_merk.text%type) is + select m.leisten_nr + from merkinh m + where m.leisten_nr = 8001 + and m.text = ic_farbe; + x_teilefarbe_exists merkinh.leisten_nr%type; + + cursor c_oberflaeche_exists(ic_oberflaeche parts.oberflaeche%type) is + select oberflaeche + from oberflaechen + where oberflaeche = ic_oberflaeche; + x_oberflaeche_exists oberflaechen.oberflaeche%type; + + cursor c_fos_gruppe_exists(ic_fos_grnr parts.fos_grnr%type) is + select grnr + from fos_grpfamsp + where grnr = ic_fos_grnr; + x_fos_gruppe_exists fos_grpfamsp.grnr%type; + + cursor c_ruestcode_exists(ic_ruestcode ruestcode_stamm.ruestcode%type) is + select ruestcode + from ruestcode_stamm + where ruestcode = ic_ruestcode; + x_ruestcode_exists ruestcode_stamm.ruestcode%type; + + cursor c_hersteller(ic_name1 varchar2) is + select kdnr, + name1 + from gepa + where name1 = ic_name1 + order by gepa_c1 desc; + xx_hersteller c_hersteller%rowtype; + + cursor c_parts_exist(ic_teilenr parts.teilenr%type) is + select teilenr + from parts + where teilenr = ic_teilenr; + x_parts_exist parts.teilenr%type; + + cursor c_parts_aend_exist(ic_teilenr parts_aend.teilenr%type, + ic_aend_index parts_aend.aend_index%type) is + select teilenr, + aend_user, + aend_dat + from parts_aend + where teilenr = ic_teilenr + and aend_index = ic_aend_index; + xx_parts_aend_exist c_parts_aend_exist%rowtype; + + cursor c_parts_aend_text_exist(ic_teilenr parts_aend_text.teilenr%type, + ic_aend_index parts_aend_text.aend_index%type) is + select teilenr + from parts_aend_text + where teilenr = ic_teilenr + and aend_index = ic_aend_index; + x_parts_aend_text_exist parts_aend_text.teilenr%type; + + x_text_lfdnr_werkstoff grnr_text.lfd_nr%type := 98; + x_text_lfdnr_farbe grnr_text.lfd_nr%type := 99; + + cursor c_grnr_text_exist(ic_teilenr grnr_text.grnr_teilenr%type, + ic_lfd_nr grnr_text.lfd_nr%type) is + select grnr_teilenr + from grnr_text g + where grnr_teilenr = ic_teilenr + and g.art = 'E' + and g.sprache = 'D' + and g.lfd_nr = ic_lfd_nr; + x_grnr_text_exist grnr_text.grnr_teilenr%type; + + cursor c_knoten_nr(ic_grnr parts.grnr%type) is + select g.knoten_nr + from grp_merkmal g + where g.grnr = ic_grnr + and g.leisten_nr = 8001; + x_knoten_nr grp_merkmal.knoten_nr%type; + + x_last_two_chars varchar2(2); + +begin + protok('k_ruledesigner.import_parts - start - i_voller_pfad: ' || i_voller_pfad, i_protok); + if i_voller_pfad is null then + o_meldung := 'k_ruledesigner.import_parts: Kein Dateipfad gegeben.'; + return false; + end if; + + if x_datei_name is null then + o_meldung := 'Konnte keinen Dateinamen aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + if x_verzeichnis is null then + o_meldung := 'Konnte kein Verzeichnis aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + -- Datei in work-Ordner verschieben + if edm.bs_verschieben(i_voller_pfad || ' ' || x_work_dir || x_datei_name) != '0' then + o_meldung := 'Fehler beim Verschieben der Datei ' || i_voller_pfad || ' in das WORK-Verzeichnis ' || x_verzeichnis || 'work/' || x_datei_name || '.'; + return false; + end if; + + -- Datei einlesen + -- execute immediate 'alter session set nls_characterset=AL32UTF8'; + x_file := sivas_utl_file.fopen(location => 'K_RD_TO_SIVAS_PARTS_WORK', + filename => x_datei_name, + open_mode => 'R', + max_linesize => 3998); + + loop + + begin + x_zeile := null; + sivas_utl_file.get_line(x_file, x_zeile, 4000); + exception + when no_data_found then + exit; + when others then + o_meldung := substr('Fehler beim Verarbeiten der Datei ''' || x_work_dir || x_datei_name || ''': ' || sqlerrm, 1, 4000); + return false; + end; + + x_zeile := trim(x_zeile); + x_last_two_chars := substr(x_zeile, -2); + + -- if p_utf then + if true then + x_text := convert(x_zeile, 'WE8ISO8859P15', 'UTF8'); + x_last_two_chars := substr(x_text, -2); + if x_last_two_chars like ';_' then + x_text := substr(x_text, 1, length(x_text) -2); + end if; + else + if x_last_two_chars like ';_' then + x_text := substr(x_zeile, 1, length(x_zeile) -2); + else + x_text := x_zeile; + end if; + end if; + + if x_header_zeile then + x_header_zeile := false; + continue; + end if; + + xx_parts := null; + xx_parts_aend := null; + xx_parts_aend_text := null; + x_erfasser_neu := null; + x_kzkauf_neu := null; + x_grnr_neu := null; + x_dispo_gruppe_neu := null; + x_dispolauf_gruppe_neu := null; + x_mengenc_neu := null; + x_farbe_neu := null; + x_alternativwerkstoff_neu := null; + x_alternativfarbe_neu := null; + x_fertigungsart_neu := null; + x_fos_grnr_neu := null; + x_abw_anzahl_jn_neu := null; + x_hz_ohne_saegeliste_neu := null; + x_hersteller_neu := null; + x_kdnr_hersteller_neu := null; + x_teilenr_hersteller_neu := null; + x_kalkart_neu := null; + x_ruestcode_neu := null; + x_serien_status := null; + x_kategorie := null; + x_spalte := 1; + for xx_werte in c_werte(x_text) loop + if xx_werte.anz != x_anz_spalten then + o_meldung := 'Innerhalb der Datei ' || x_work_dir || x_datei_name || ' gibt es eine Zeile die nicht genau ' || x_anz_spalten || ' Spalten beinhaltet.'; + return false; + end if; + + if x_spalte = x_spalte_teilenr then + if length(xx_werte.wert) > 20 or xx_werte.wert is null then + o_meldung := 'Ungueltige Teilenummer: ' || xx_werte.wert || '.'; + return false; + end if; + open c_parts_exists(xx_werte.wert); + fetch c_parts_exists into x_parts_exists; + close c_parts_exists; + if x_parts_exists is not null then + xx_parts := standard_cursor.parts_lesen(i_teilenr => xx_werte.wert); + else + xx_parts.teilenr := xx_werte.wert; + end if; + + elsif x_spalte = x_spalte_bez then + if length(xx_werte.wert) > 50 or xx_werte.wert is null then + o_meldung := 'Ungueltige Teilebezeichnung: ' || xx_werte.wert || '.'; + return false; + end if; + if nvl(xx_werte.wert, 'XY') like '- %' then + xx_parts.bez := trim(substr(xx_werte.wert, 2)); + else + xx_parts.bez := trim(xx_werte.wert); + end if; + elsif x_spalte = x_spalte_ersteller and xx_werte.wert is not null then + if length(xx_werte.wert) > 20 then + o_meldung := 'Ungueltiger Ersteller: ' || xx_werte.wert || '.'; + return false; + end if; + x_erfasser_neu := rd_user_to_sivas(xx_werte.wert); + + elsif x_spalte = x_spalte_aenderer and xx_werte.wert is not null then + if length(xx_werte.wert) > 20 then + o_meldung := 'Ungueltiger Aenderer: ' || xx_werte.wert || '.'; + return false; + end if; + xx_parts.aend_user := rd_user_to_sivas(xx_werte.wert); + + elsif x_spalte = x_spalte_index then + if xx_werte.wert is null then + o_meldung := 'Kein Aenderungsindex mitgegeben.'; + return false; + end if; + + if length(xx_werte.wert) > 10 then + o_meldung := 'Ungueltiger Aenderungsindex: ' || xx_werte.wert || '.'; + return false; + end if; + xx_parts_aend.teilenr := xx_parts.teilenr; + xx_parts_aend.aend_index := upper(trim(xx_werte.wert)); + xx_parts_aend.freigabe_user := x_erfasser_neu; + xx_parts_aend.freigabe_datum := sysdate; + + elsif x_spalte = x_spalte_kzkauf and xx_werte.wert is not null then + if upper(substr(xx_werte.wert, 1, 1)) not in ('E', 'K') or xx_werte.wert is null then + o_meldung := 'Ungueltige Beschaffungsart: ' || xx_werte.wert || '.'; + return false; + end if; + -- xx_parts.kzkauf := upper(substr(xx_werte.wert, 1, 1)); + x_kzkauf_neu := upper(substr(xx_werte.wert, 1, 1)); + + elsif x_spalte = x_spalte_grnr and xx_werte.wert is not null then + if length(xx_werte.wert) > 6 then + o_meldung := 'Ungueltige TOS-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + x_grnr_exists := null; + open c_grnr_exists(xx_werte.wert); + fetch c_grnr_exists into x_grnr_exists; + close c_grnr_exists; + if x_grnr_exists is null then + o_meldung := 'Ungueltige TOS-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + x_grnr_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_dispogr and xx_werte.wert is not null then + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + o_meldung := 'Ungueltige Dispo-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + open c_dispogr_exists(to_number(xx_werte.wert)); + fetch c_dispogr_exists into x_dispogr_exists; + close c_dispogr_exists; + if x_dispogr_exists is null then + o_meldung := 'Ungueltige Dispo-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.dispo_gruppe := to_number(xx_werte.wert); + x_dispo_gruppe_neu := to_number(xx_werte.wert); + + elsif x_spalte = x_spalte_dispolauf and xx_werte.wert is not null then + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + o_meldung := 'Ungueltige Dispolaufgruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + x_dispolaufgruppe_exists := null; + open c_dispolaufgruppe_exists(to_number(xx_werte.wert)); + fetch c_dispolaufgruppe_exists into x_dispolaufgruppe_exists; + close c_dispolaufgruppe_exists; + if x_dispolaufgruppe_exists is null then + o_meldung := 'Ungueltige Dispolaufgruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.dispolauf_gruppe := to_number(xx_werte.wert); + x_dispolauf_gruppe_neu := to_number(xx_werte.wert); + + elsif x_spalte = x_spalte_mengenc and xx_werte.wert is not null then + if length(xx_werte.wert) > 4 then + o_meldung := 'Ungueltige Mengeneinheit: ' || xx_werte.wert || '.'; + return false; + end if; + + x_mengeneinheit_exists := null; + open c_mengeneinheit_exists(xx_werte.wert); + fetch c_mengeneinheit_exists into x_mengeneinheit_exists; + close c_mengeneinheit_exists; + if x_mengeneinheit_exists is null then + o_meldung := 'Ungueltige Mengeneinheit: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.mengenc := xx_werte.wert; + x_mengenc_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_ersetzt_teil and xx_werte.wert is not null then + if length(xx_werte.wert) > 2000 then + o_meldung := 'Ungueltiger Wert fuer ''Ersetzt'': ' || xx_werte.wert || '.'; + return false; + end if; + + x_parts_exist := null; + open c_parts_exist(xx_werte.wert); + fetch c_parts_exist into x_parts_exist; + close c_parts_exist; + if x_parts_exist is null then + o_meldung := 'Ungueltiger Wert fuer ''Ersetzt'': ' || xx_werte.wert || '.'; + return false; + end if; + + xx_parts.info25 := xx_werte.wert; + + elsif x_spalte = x_spalte_ersetz_durch and xx_werte.wert is not null then + if length(xx_werte.wert) > 21 then + o_meldung := 'Ungueltiger Wert fuer ''Ersetzt von'': ' || xx_werte.wert || '.'; + return false; + end if; + + x_parts_exist := null; + open c_parts_exist(xx_werte.wert); + fetch c_parts_exist into x_parts_exist; + close c_parts_exist; + if x_parts_exist is null then + o_meldung := 'Ungueltiger Wert fuer ''Ersetzt von''. Das Teil ''' || xx_werte.wert || ''' ist nicht im SIVAS-Teilestamm erfasst.'; + return false; + end if; + + xx_parts.verknummer := xx_werte.wert; + + elsif x_spalte = x_spalte_werkstoff and xx_werte.wert is not null then + if length(xx_werte.wert) > 4000 then + o_meldung := 'Ungueltiger Werkstoff: ' || xx_werte.wert || '.'; + return false; + end if; + + x_werkstoff_exists := null; + open c_werkstoff_exists(xx_werte.wert); + fetch c_werkstoff_exists into x_werkstoff_exists; + close c_werkstoff_exists; + if x_werkstoff_exists is null then + o_meldung := 'Ungueltiger Werkstoff: ' || xx_werte.wert || '.'; + return false; + end if; + + xx_parts.werkstoff := xx_werte.wert; + + elsif x_spalte = x_spalte_oberflaeche and xx_werte.wert is not null then + if length(xx_werte.wert) > 200 then + o_meldung := 'Ungueltige Oberflaechenbehandlung: ' || xx_werte.wert || '.'; + return false; + end if; + + x_oberflaeche_exists := null; + open c_oberflaeche_exists(xx_werte.wert); + fetch c_oberflaeche_exists into x_oberflaeche_exists; + close c_oberflaeche_exists; + if x_oberflaeche_exists is null then + o_meldung := 'Ungueltige Oberflaechenbehandlung: ' || xx_werte.wert || '.'; + return false; + end if; + + xx_parts.oberflaeche := xx_werte.wert; + + elsif x_spalte = x_spalte_farbe and xx_werte.wert is not null then + if length(xx_werte.wert) > 4000 then + o_meldung := 'Ungueltige Farbe: ' || xx_werte.wert || '.'; + return false; + end if; + + open c_teilefarbe_exists(xx_werte.wert); + fetch c_teilefarbe_exists into x_teilefarbe_exists; + close c_teilefarbe_exists; + if x_teilefarbe_exists is null then + o_meldung := 'Farbe: ' || xx_werte.wert || ' nicht als SIVAS-Merkmal der Leistennr. 8001 definiert.'; + return false; + end if; + + x_farbe_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_alternativ_werkstoff and xx_werte.wert is not null then + if length(xx_werte.wert) > 4000 or xx_werte.wert is null then + o_meldung := 'Ungueltiger Alternativwerkstoff: ' || xx_werte.wert || '.'; + return false; + end if; + + -- x_alternativ_werkstoff := xx_werte.wert; + x_alternativwerkstoff_neu := 'Alternativwerkstoff: ' || xx_werte.wert; + + elsif x_spalte = x_spalte_alternaiv_farbe and xx_werte.wert is not null then + if length(xx_werte.wert) > 4000 or xx_werte.wert is null then + o_meldung := 'Ungueltige Alternativfarbe: ' || xx_werte.wert || '.'; + return false; + end if; + x_alternativfarbe_neu := 'Alternativfarbe: ' || xx_werte.wert; + + elsif x_spalte = x_spalte_fertigungsart and xx_werte.wert is not null then + if length(xx_werte.wert) > 2 then + o_meldung := 'Ungueltige Fertigungsart: ' || xx_werte.wert || '.'; + return false; + end if; + + open c_fertigungsteil_exists(xx_werte.wert); + fetch c_fertigungsteil_exists into x_fertigungsteil_exists; + close c_fertigungsteil_exists; + if x_fertigungsteil_exists is null then + o_meldung := 'Ungueltige Fertigungsart: ' || xx_werte.wert || '.'; + return false; + end if; + + x_fertigungsart_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_fos_gruppe and xx_werte.wert is not null then + if length(xx_werte.wert) > 6 then + o_meldung := 'Ungueltige FOS-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + x_fos_gruppe_exists := null; + open c_fos_gruppe_exists(xx_werte.wert); + fetch c_fos_gruppe_exists into x_fos_gruppe_exists; + close c_fos_gruppe_exists; + if x_fos_gruppe_exists is null then + o_meldung := 'Ungueltige FOS-Gruppe: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.fos_grnr := xx_werte.wert; + x_fos_grnr_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_aend_text and xx_werte.wert is not null and xx_parts_aend.aend_index is not null then + if length(xx_werte.wert) > 4000 then + o_meldung := 'Ungueltiger Aenderungstext: ' || xx_werte.wert || '.'; + return false; + end if; + xx_parts_aend_text.teilenr := xx_parts_aend.teilenr; + xx_parts_aend_text.aend_index := xx_parts_aend.aend_index; + xx_parts_aend_text.unter_ind := 0; + xx_parts_aend_text.manu := 1; + xx_parts_aend_text.sprache := 'D'; + xx_parts_aend_text.text := xx_werte.wert; + + elsif x_spalte = x_spalte_freigabe_text and xx_werte.wert is not null then + if length(xx_werte.wert) > 4000 then + o_meldung := 'Ungueltiger Freigabevermerk: ' || xx_werte.wert || '.'; + return false; + end if; + xx_parts_aend.freigabevermerk := xx_werte.wert; + + elsif x_spalte = x_spalte_halbzeug_jn and xx_werte.wert is not null then + if length(xx_werte.wert) > 1 or upper(nvl(xx_werte.wert, 'N')) not in ('N', 'J') then + o_meldung := 'Ungueltiger Halbzeugkenner: ' || xx_werte.wert || '.'; + return false; + end if; + -- xx_parts.abw_anzahl_jn := upper(nvl(xx_werte.wert, 'N')); + x_abw_anzahl_jn_neu := upper(nvl(xx_werte.wert, 'N')); + + elsif x_spalte = x_spalte_bez_halbzeug then + if length(xx_werte.wert) > 2000 then + o_meldung := 'Ungueltige Halbzeugsbezeichnung: ' || xx_werte.wert || '.'; + return false; + end if; + xx_parts.info16 := xx_werte.wert; + + elsif x_spalte = x_spalte_hz_ohne_saegeliste and xx_werte.wert is not null then + if length(xx_werte.wert) > 1 or upper(nvl(xx_werte.wert, 'N')) not in ('N', 'J') then + o_meldung := 'Ungueltige Wert fuer ''Halbzeug ohne Saegeliste'': ' || xx_werte.wert || '.'; + return false; + end if; + -- xx_parts.info2_jn := upper(nvl(xx_werte.wert, 'N')); + x_hz_ohne_saegeliste_neu := upper(nvl(xx_werte.wert, 'N')); + + elsif x_spalte = x_spalte_hersteller and xx_werte.wert is not null then + if length(xx_werte.wert) > 200 then + o_meldung := 'Ungueltiger Hersteller: ' || xx_werte.wert || '.'; + return false; + end if; + + xx_hersteller.kdnr := null; + open c_hersteller(xx_werte.wert); + fetch c_hersteller into xx_hersteller; + close c_hersteller; + if xx_hersteller.kdnr is null then + o_meldung := 'Ungueltiger Hersteller: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.kdnr_hersteller := xx_hersteller.kdnr; + -- xx_parts.hersteller := xx_hersteller.name1; + + x_hersteller_neu := xx_hersteller.name1; + x_kdnr_hersteller_neu := xx_hersteller.kdnr; + + elsif x_spalte = x_spalte_hersteler_teilenr and xx_werte.wert is not null then + if length(xx_werte.wert) > 100 then + o_meldung := 'Ungueltiger Herstellerteilenummer: ' || xx_werte.wert || '.'; + return false; + end if; + -- xx_parts.teilenr_hersteller := xx_werte.wert; + x_teilenr_hersteller_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_kalkart and xx_werte.wert is not null then + if length(xx_werte.wert) > 2000 then + o_meldung := 'Ungueltige Kalkulationsart: ' || xx_werte.wert || '.'; + return false; + end if; + -- xx_parts.info14 := xx_werte.wert; + x_kalkart_neu := xx_werte.wert; + + elsif x_spalte = x_spalte_ruestcode and xx_werte.wert is not null then + if length(xx_werte.wert) > 4 then + o_meldung := 'Ungueltiger Ruestcode: ' || xx_werte.wert || '.'; + return false; + end if; + + x_ruestcode_exists := null; + open c_ruestcode_exists(xx_werte.wert); + fetch c_ruestcode_exists into x_ruestcode_exists; + close c_ruestcode_exists; + if x_ruestcode_exists is null then + o_meldung := 'Ungueltiger Ruestcode: ' || xx_werte.wert || '.'; + return false; + end if; + + -- xx_parts.ruestcode := xx_werte.wert; + x_ruestcode_neu := xx_werte.wert; + elsif x_spalte = x_spalte_serienstatus then + x_serien_status := xx_werte.wert; + elsif x_spalte = x_spalte_kategorie then + x_kategorie := xx_werte.wert; + end if; + + x_spalte := x_spalte + 1; + end loop; + + xx_parts.erfass_user := nvl(xx_parts.erfass_user, x_erfasser_neu); + xx_parts.erfass_dat := nvl(xx_parts.erfass_dat, sysdate); + xx_parts.aend_dat := nvl(xx_parts.aend_dat, sysdate); + xx_parts.dispo_aktiv_jn := nvl(xx_parts.dispo_aktiv_jn, 'J'); + + -- Nur Felder beschreiben, wenn Revision 'A' ist + if nvl(xx_parts_aend.aend_index, 'XYZ') = 'A' then + xx_parts.grnr := x_grnr_neu; + xx_parts.dispo_gruppe := x_dispo_gruppe_neu; + xx_parts.dispolauf_gruppe := x_dispolauf_gruppe_neu; + xx_parts.mengenc := x_mengenc_neu; + xx_parts.c_teil_art := x_fertigungsart_neu; + xx_parts.fos_grnr := x_fos_grnr_neu; + xx_parts.abw_anzahl_jn := x_abw_anzahl_jn_neu; + xx_parts.info2_jn := x_hz_ohne_saegeliste_neu; + xx_parts.hersteller := x_hersteller_neu; + xx_parts.kdnr_hersteller := x_kdnr_hersteller_neu; + xx_parts.teilenr_hersteller := x_teilenr_hersteller_neu; + xx_parts.info14 := x_kalkart_neu; + xx_parts.ruestcode := x_ruestcode_neu; + end if; + + if upper(nvl(x_serien_status, 'XYZ')) = 'PROTOTYP' then + x_alternativ_werkstoff := x_alternativwerkstoff_neu; + x_alternativ_farbe := x_alternativfarbe_neu; + elsif upper(nvl(x_serien_status, 'XYZ')) = 'SERIE' then + x_alternativ_werkstoff := null; + x_alternativ_farbe := null; + end if; + + if xx_parts_aend.aend_index is not null then + if x_farbe_neu is not null then + x_knoten_nr := null; + open c_knoten_nr(x_grnr_neu); + fetch c_knoten_nr into x_knoten_nr; + close c_knoten_nr; + + if x_knoten_nr is null then + o_meldung := 'Fuer die TOS-Gruppe ' || x_grnr_neu || ' ist das Merkmal Teilefarbe nicht gepflegt.'; + return false; + end if; + end if; + end if; + + xx_parts.manu := 1; + x_parts_exist := null; + open c_parts_exist(xx_parts.teilenr); + fetch c_parts_exist into x_parts_exist; + close c_parts_exist; + if x_parts_exist is null then + + -- AJ/20240701: Beschaffungsart nur bei Neuanlagen + xx_parts.kzkauf := x_kzkauf_neu; + + insert into parts values xx_parts; + else + update parts set row = xx_parts where teilenr = xx_parts.teilenr; + end if; + + if xx_parts_aend.aend_index is not null then + xx_parts_aend.unter_ind := 0; + xx_parts_aend.manu := 1; + xx_parts_aend_exist := null; + open c_parts_aend_exist(xx_parts_aend.teilenr, xx_parts_aend.aend_index); + fetch c_parts_aend_exist into xx_parts_aend_exist; + close c_parts_aend_exist; + + if upper(xx_parts_aend.aend_index) = 'A' then + xx_parts_aend.aend_user := x_erfasser_neu; + xx_parts_aend.aend_dat := sysdate; + xx_parts_aend.freigabe_user := x_erfasser_neu; + xx_parts_aend.freigabe_datum := sysdate; + + if x_farbe_neu is not null then + delete from teil_merk + where teilenr = xx_parts.teilenr + and leisten_nr = 8001; + + insert into teil_merk (teilenr, + leisten_nr, + sprache, + text, + manu, + erfasser, + erfass_datum, + bem, + knoten_nr) + values(xx_parts.teilenr, + 8001, + 'D', + x_farbe_neu, + 1, + user, + sysdate, + 'Aus RuleDesigner importiert', + x_knoten_nr); + end if; + else + xx_parts_aend.aend_user := xx_parts.aend_user; + xx_parts_aend.aend_dat := sysdate; + xx_parts_aend.freigabe_user := xx_parts.aend_user; + xx_parts_aend.freigabe_datum := sysdate; + end if; + + if xx_parts_aend_exist.teilenr is null then + -- xx_parts_aend.aend_user := x_erfasser_neu; + -- xx_parts_aend.aend_dat := sysdate; + insert into parts_aend values xx_parts_aend; + else + update parts_aend + set row = xx_parts_aend + where teilenr = xx_parts_aend.teilenr + and aend_index = xx_parts_aend.aend_index; + end if; + + if xx_parts_aend_text.teilenr is not null and xx_parts_aend_text.aend_index is not null then + xx_parts_aend_text.unter_ind := 0; + xx_parts_aend_text.manu := 1; + x_parts_aend_text_exist := null; + open c_parts_aend_text_exist(xx_parts_aend_text.teilenr, xx_parts_aend_text.aend_index); + fetch c_parts_aend_text_exist into x_parts_aend_text_exist; + close c_parts_aend_text_exist; + if x_parts_aend_text_exist is null then + insert into parts_aend_text values xx_parts_aend_text; + else + update parts_aend_text + set row = xx_parts_aend_text + where teilenr = xx_parts_aend_text.teilenr + and aend_index = xx_parts_aend_text.aend_index; + end if; + end if; + end if; + + if upper(nvl(x_serien_status, 'XYZ')) = 'SERIE' and upper(xx_parts_aend.aend_index) = 'A' then + null; + elsif x_alternativ_werkstoff is not null then + xx_grnr_text := null; + xx_grnr_text.grnr_teilenr := xx_parts.teilenr; + xx_grnr_text.lfd_nr := x_text_lfdnr_werkstoff; + xx_grnr_text.art := 'E'; + xx_grnr_text.sprache := 'D'; + xx_grnr_text.text := x_alternativ_werkstoff; + xx_grnr_text.text_nclob := sivas_net_rtf.text_to_rtf(itxt => x_alternativ_werkstoff, + ischriftart => 'Arial', + ischriftgroesse => 10); + + x_grnr_text_exist := null; + open c_grnr_text_exist(xx_grnr_text.grnr_teilenr, + xx_grnr_text.lfd_nr); + fetch c_grnr_text_exist into x_grnr_text_exist; + close c_grnr_text_exist; + if x_grnr_text_exist is null then + insert into grnr_text values xx_grnr_text; + else + update grnr_text + set row = xx_grnr_text + where grnr_teilenr = xx_grnr_text.grnr_teilenr + and art = 'E' + and sprache = 'D' + and lfd_nr = xx_grnr_text.lfd_nr; + end if; + end if; + + if upper(nvl(x_serien_status, 'XYZ')) = 'SERIE' and upper(xx_parts_aend.aend_index) = 'A' then + null; + elsif x_alternativ_farbe is not null then + xx_grnr_text := null; + xx_grnr_text.grnr_teilenr := xx_parts.teilenr; + xx_grnr_text.lfd_nr := x_text_lfdnr_farbe; + xx_grnr_text.art := 'E'; + xx_grnr_text.sprache := 'D'; + xx_grnr_text.text := x_alternativ_farbe; + xx_grnr_text.text_nclob := sivas_net_rtf.text_to_rtf(itxt => x_alternativ_farbe, + ischriftart => 'Arial', + ischriftgroesse => 10); + + x_grnr_text_exist := null; + open c_grnr_text_exist(xx_grnr_text.grnr_teilenr, + xx_grnr_text.lfd_nr); + fetch c_grnr_text_exist into x_grnr_text_exist; + close c_grnr_text_exist; + if x_grnr_text_exist is null then + insert into grnr_text values xx_grnr_text; + else + update grnr_text + set row = xx_grnr_text + where grnr_teilenr = xx_grnr_text.grnr_teilenr + and art = 'E' + and sprache = 'D' + and lfd_nr = xx_grnr_text.lfd_nr; + end if; + end if; + end loop; + + sivas_utl_file.fclose(x_file); + + return true; +end; + +-------------------------------------------------------------------------------------------- + +function stkl_archiv_erstellen(i_uebteilenr in comp.uebteilenr%type, + i_custom in boolean default false, + i_force in boolean default false) return boolean is + + cursor c_comp_exists is + select kompteilenr + from comp + where uebteilenr = i_uebteilenr; + x_comp_exists comp.kompteilenr%type; + + cursor c_parts_aend_freig is + select max(pa.aend_index) aend_index + from parts_aend pa + where pa.teilenr = i_uebteilenr + and pa.freigabe_datum = nvl((select max(paa.freigabe_datum) + from parts_aend paa + where paa.teilenr = i_uebteilenr), pa.freigabe_datum); + xx_parts_aend_freig c_parts_aend_freig%rowtype; + + cursor c_comp_kopf_hist(ic_aend_index parts_aend.aend_index%type) is + select * + from comp_kopf_hist h + where h.uebteilenr = i_uebteilenr + and h.aend_index = ic_aend_index; + xx_comp_kopf_hist comp_kopf_hist%rowtype; + + x_erstellt boolean := false; + +begin + open c_comp_exists; + fetch c_comp_exists into x_comp_exists; + close c_comp_exists; + + if x_comp_exists is null then + return x_erstellt; + end if; + + open c_parts_aend_freig; + fetch c_parts_aend_freig into xx_parts_aend_freig; + close c_parts_aend_freig; + + if xx_parts_aend_freig.aend_index is null then + return x_erstellt; + end if; + + xx_comp_kopf_hist := null; + open c_comp_kopf_hist(xx_parts_aend_freig.aend_index); + fetch c_comp_kopf_hist into xx_comp_kopf_hist; + close c_comp_kopf_hist; + + -- AJ/20240703: + -- Stücklistenarchiv soll laut SS mehrfach geschrieben werden + + -- Stuecklistenarchiv anlegen + if xx_comp_kopf_hist.lfdnr_hist is null or i_force then + if i_custom then + sivas_aj.k_sb_rd_stkl_pck.erstelle_comp_hist(i_uebteilenr, 'Erstellt durch Import aus RuleDesigner.'); + else + stkl_pck.erstelle_comp_hist(i_uebteilenr, 'Erstellt durch Import aus RuleDesigner.'); + end if; + x_erstellt := true; + end if; + + return x_erstellt; +end; + +-------------------------------------------------------------------------------------------- + +/* +Wenn Positionsnummern folgende Kriterien erfüllen, sollen Sie in einer Workflowmeldung an die AV-Verantwortlichen ausgegeben werden: + +Kriterien: +WENN die Positionen zu einer längenabhängigen Teilenummer MIT Sägeliste gehören (d.h. Haken bei 'Halbzeug ohne Sägeliste' im Teilestamm ist nicht gesetzt) +UND diese längenabhängige Teilenummer in der alten und der neuen Stückliste vertreten ist +UND die Länge-Teilenummer-Kombination dieser Positionsnummer nur in der alten Stückliste vorliegt (aber nicht in der Neuen) +UND bei der Position mindestens eine der nachfolgenden Kriterien erfüllt ist: + - der Wert in der Spalte 'Rüstcode' weicht vom Rüstcode-Wert ab, den die zugehörige Teilenummer im Teilstamm aufweist + - in der Spalte 'Dispoaktiv' liegt kein Haken vor + - in der Spalte 'Zuschnitt' ist ein Wert definiert +*/ + +procedure send_av_wfs(i_uebteilenr in comp.uebteilenr%type, + i_pfad in varchar2) is + cursor c_data is + select c.posnr, + c.kompteilenr + from comp c + left join k_sb_rd_comp rd + on c.uebteilenr = rd.uebteilenr + and c.kompteilenr = rd.kompteilenr + and coalesce(c.laenge, 0) = rd.laenge + inner join parts p + on c.kompteilenr = p.teilenr + where c.uebteilenr = i_uebteilenr + and c.kompteilenr in (select distinct kompteilenr -- Nur längenabhängige Teilenummern berücksichtigen, die in beiden Stücklisten vorliegen + from k_sb_rd_comp + where uebteilenr = i_uebteilenr + and kompteilenr in ( select distinct kompteilenr + from comp + where uebteilenr = i_uebteilenr + and coalesce(laenge, 0) != 0 )) + and rd.uebteilenr is null -- Nur Positionen berücksichtigen, deren Länge ausschließlich in der alten Stückliste vorliegt + and nvl(p.info2_jn, 'N') = 'N' -- Nur Positionen berücksichtigen, deren zugehörige Teilenummer keinen Haken bei "Halbzeug ohne Sägeliste" im Teilestamm aufweist + and ( -- Nur Positionen berücksichtigen, auf die min. eines der nachfolgenden Kriterien zutrifft: + c.zuschnitt is not null -- Zuschnittswert liegt vor + or nvl(c.ruestcode, 'X') != nvl(p.ruestcode, 'Y') -- Rüstcode der Position in der Stammstückliste ist abweichend zum Rüstcode der zugehörigen Teilenummer im Teilestamm + or nvl(c.dispo_aktiv_jn, 'N') = 'N' -- Stücklistenpositionen besitzt keinen Haken in der Spalte "Dispoaktiv" + ) + order by c.posnr; + + x_liste varchar2(4000); +begin + for xx_data in c_data loop + if x_liste is not null then + x_liste := x_liste || ', '; + end if; + x_liste := x_liste || xx_data.posnr || ' - ' || xx_data.kompteilenr; + end loop; + + if x_liste is null then + return; + end if; + + rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_av => 'Bitte Stückliste ' || i_uebteilenr || ' prüfen. Vor der Änderung lagen bei folgenden Positionen manuelle Eintragungen / Änderungen in den Spalten ''Zuschnitt'', ''Rüstcode'' oder ''Dispoaktiv'' vor: ' || x_liste); +end; + +-------------------------------------------------------------------------------------------- + +/* +Wenn Positionsnummern in der Stückliste TOS-Regeln oder -Bedingungen aufweisen, + sollen Sie in einer Workflowmeldung an die TOS-Verantwortlichen ausgegeben werden. +*/ + +procedure send_tos_wfs(i_uebteilenr in comp.uebteilenr%type, + i_pfad in varchar2) is + cursor c_data is + select c.posnr, c.kompteilenr + from comp c + left join var_teil_bedingung_2 b + on c.uebteilenr = b.uebteilenr + and c.posnr = b.posnr + left join stkl_regel r + on c.uebteilenr = r.uebteilenr + and c.posnr = r.posnr + where c.uebteilenr = i_uebteilenr + and ( b.ueb_leisten_nr is not null or r.lfd_nr is not null ) + order by c.posnr; + + x_liste varchar2(4000); +begin + for xx_data in c_data loop + if x_liste is not null then + x_liste := x_liste || ', '; + end if; + x_liste := x_liste || xx_data.posnr || ' - ' || xx_data.kompteilenr; + end loop; + + if x_liste is null then + return; + end if; + + rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_tos => 'Bitte Stückliste ' || i_uebteilenr || ' prüfen. Vor der Änderung lagen bei folgenden Positionen TOS-Regeln oder -Bedingungen vor: ' || x_liste); +end; + +-------------------------------------------------------------------------------------------- + +/* +Ermittelt alle Teilenummern, die unter Fall 1.2 oder Fall 1.3 fallen. +Es wird dafür geprüft, welche Teilenummern NICHT unter Fall 1.1 fallen. + +Wieso wird nicht geprüft, welche Teilenummern in Fall 1.1 liegen? +- Weil die SQL-Abfrage dann komplexer wird. + +Die Prüfung läuft so ab: +1. Teilenr-Längen-Kombinationen aus der alten und neuen Stückliste mit UNION ALL verschmelzen +2. Mit COUNT ermitteln, wie oft jede Teilenummer-Längen-Kombination in der verschmolzenen Stückliste auftritt +3. Die Teilenummern in die temporäre Tabelle c schreiben, sobald 1x eine Teilenr-Längen-Kombination auftritt, die nur 1x vorkommt + => Diese Teilenummern unterliegen entweder Fall 1.2 oder Fall 1.3, aber definitiv nicht Fall 1.1, weil eine Zuordnung zu Fall 1.1 nur dann möglich ist, + wenn alle Teilenr-Längen-Kombinationen einer Teilenummer exakt 2x auftreten! +*/ + +procedure get_codes_case_12_or_13(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select distinct y.kompteilenr + from ( select x.kompteilenr, + x.laenge, + count(*) as anzahl + from (select c.kompteilenr, + coalesce(c.laenge, 0) as laenge + from comp c + where c.uebteilenr = i_uebteilenr + union all + select kompteilenr, laenge + from k_sb_rd_comp + where uebteilenr = i_uebteilenr) x + group by x.kompteilenr, + x.laenge ) y + where y.anzahl = 1; + +begin + delete from tmp_codes_case_12_or_13; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_codes_case_12_or_13 (kompteilenr) + values (xx_combined_bom.kompteilenr); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Ermittelt alle Teilenummern, die unter Fall 1.3 fallen + +Fall 1.3 umfasst alle Positionen, die entweder in der neuen Stückliste dazugekommen sind (Fall 1.31) oder deren +Teilenr-Längen-Kombination in beiden Stücklisten vorliegen (Fall 1.32). + +Wenn Positionen bereits unter Fall 1.1 oder Fall 1.2 fallen, dann werden sie NICHT Fall 1.32 zugeordnet, selbst wenn +Fall 1.32 auf diese Positionen zutreffen würde. + +Die Prüfung läuft so ab: +1. Alle Teilenr-Posnr-Kombinationen aus der alten und neuen Stückliste mit UNION ALL verschmelzen, sofern sich die Teilenummern in der + Liste an Teilenummern befindet, die unter Fall 1.2 oder Fall 1.3 fallen (siehe Methode _get_codes_case_12_or_13()) +2. Mit COUNT ermitteln, wie oft jede Teilenr-Posnr-Kombination in der zusammengefügten Stückliste auftritt +3. Die Teilenummern, deren Teilenr-Posnr-Kombination nur 1x auftritt, in die temporäre Tabelle TMP_CODES_CASE_13 schreiben + => Diese Teilenummern unterliegen definitv Fall 1.3, weil in Fall 1.2 alle Teilenr-Posnr-Kombinationen einer Teilenummer exakt 2x auftreten müssen! +*/ + +procedure get_codes_case_13(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select distinct y.kompteilenr + from ( select x.kompteilenr, + count(*) as anzahl + from (select kompteilenr, + posnr + from comp + where uebteilenr = i_uebteilenr + and kompteilenr in (select kompteilenr from tmp_codes_case_12_or_13) + union all + select kompteilenr, + posnr + from k_sb_rd_comp + where uebteilenr = i_uebteilenr + and kompteilenr in (select kompteilenr from tmp_codes_case_12_or_13)) x + group by x.kompteilenr, + x.posnr ) y + where y.anzahl = 1; +begin + delete from tmp_codes_case_13; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_codes_case_13 (kompteilenr) + values (xx_combined_bom.kompteilenr); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Holt sich die Positionsnummern, die unter Fall 1.1 fallen. + +Deren Ermittlung funktioniert so: +1. Teilenummern herausfiltern, die NICHT in der Tabelle TMP_CODES_CASE_12_OR_13 vorliegen +2. Zu den gefundenen Teilenummern folgende Spaltenwerte ermitteln und in die temporäre Tabelle TMP_POSNRS_CASE_11 schreiben: + - Teilenr des Parents + - Positionsnummer laut alter Stückliste + - Positionsnummer laut neuer Stückliste + + Hinweis: + - Die Positionsnummern aus beiden Stücklisten werden benötigt, um bei der Ermittlung der Update-Daten die Zuordnung zwischen der alten und neuen + Stückliste herstellen zu können + - Die Teilenummer des Parents wird zusamment mit der Positionsnummer laut alter Stückliste dafür benötigt, um in den Tabellen STKL_REGEL und + VAR_TEIL_BEDINGUNG_2 die Zeilen zu ermitteln, die aktualisiert werden müssen +*/ + +procedure get_case_11_positions(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select c.uebteilenr, + c.posnr pos_alt, + rd.posnr pos_neu + from k_sb_rd_comp rd + left join tmp_codes_case_12_or_13 tmp + on rd.kompteilenr = tmp.kompteilenr + left join comp c + on rd.uebteilenr = c.uebteilenr + and rd.kompteilenr = c.kompteilenr + and rd.laenge = coalesce(c.laenge, 0) + where rd.uebteilenr = i_uebteilenr + and tmp.kompteilenr is null; +begin + delete from tmp_posnrs_case_11; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_posnrs_case_11 (uebteilenr, + pos_alt, + pos_neu) + values (xx_combined_bom.uebteilenr, + xx_combined_bom.pos_alt, + xx_combined_bom.pos_neu); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Holt sich die Positionsnummern, die unter Fall 1.2 fallen. + +Deren Ermittlung funktioniert so: +1. Teilenummern herausfiltern, die in der Tabelle TMP_CODES_CASE_12_OR_13, aber NICHT in Tabelle TMP_CODES_CASE_13 existieren +2. Zu den gefundenen Teilenummern folgende Spaltenwerte ermitteln und in die temporäre Tabelle TMP_POSNRS_CASE_12 schreiben: + - Teilenr des Parents + - Positionsnummer laut alter Stückliste + - Positionsnummer laut neuer Stückliste + + Hinweis: + - Die Positionsnummern aus beiden Stücklisten werden benötigt, um bei der Ermittlung der Update-Daten die Zuordnung zwischen der alten und neuen + Stückliste herstellen zu können + - Die Teilenummer des Parents wird zusamment mit der Positionsnummer laut alter Stückliste dafür benötigt, um in den Tabellen STKL_REGEL und + VAR_TEIL_BEDINGUNG_2 die Zeilen zu ermitteln, die aktualisiert werden müssen +*/ + +procedure get_case_12_positions(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select c.uebteilenr, + c.posnr as pos_alt, + rd.posnr as pos_neu + from k_sb_rd_comp rd + left join tmp_codes_case_13 tmp + on rd.kompteilenr = tmp.kompteilenr + left join comp c + on rd.uebteilenr = c.uebteilenr + and rd.kompteilenr = c.kompteilenr + and rd.posnr = c.posnr + where rd.uebteilenr = i_uebteilenr + and tmp.kompteilenr is null + and rd.posnr not in (select pos_neu from tmp_posnrs_case_11); +begin + delete from tmp_posnrs_case_12; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_posnrs_case_12 (uebteilenr, + pos_alt, + pos_neu) + values (xx_combined_bom.uebteilenr, + xx_combined_bom.pos_alt, + xx_combined_bom.pos_neu); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Fall 1.31 - Positionsnummern ermitteln, die neu angelegt werden müssen. + +Deren Ermittlung funktioniert so: +1. Alle Positionsnummern herausfiltern, auf die folgende Kriterien zutreffen: + - Teilenr-Längen-Kombination der Position existiert nur in der neuen Stückliste existiert + - Teilenummer der Position ist in der Tabelle TMP_CODES_CASE_13 enthalten + + Hinweis: + Es reicht nicht aus, lediglich zu prüfen, ob die Teilenr-Längen-Kombination nur in der neuen Stückliste vorliegt + Grund: + Positionsnummern die unter Fall 1.2 fallen, dürfen in der neuen Stückliste eine andere Teilenr-Längen-Kombination + als in der alten Stückliste aufweisen, d.h. die Teilenr-Längen-Kombi laut neuer Stückliste liegt auch nur dort vor. Trotzdem + werden diese Positionsnummern nicht neu angelegt, sondern von der alten in die neuen Stückliste verschoben! + +2. Alle gefundenen Positionen in die temporäre Tabelle TMP_POSNRS_CASE_131 schreiben (mehr Informationen werden nicht benötigt) +*/ + +procedure get_case_131_positions(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select rd.posnr as posnr + from k_sb_rd_comp rd + left join comp c + on rd.uebteilenr = c.uebteilenr + and rd.kompteilenr = c.kompteilenr + and rd.laenge = coalesce(c.laenge, 0) + where rd.uebteilenr = i_uebteilenr + and rd.kompteilenr in (select kompteilenr from tmp_codes_case_13) + and c.kompteilenr is null; +begin + delete from tmp_posnrs_case_131; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_posnrs_case_131 (posnr) values (xx_combined_bom.posnr); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Fall 1.32 - Positionsnummern holen, die von der alten in die neue Stückliste verschoben werden + +Deren Ermittlung funktioniert so: +1. Alle Positionsnummern herausfiltern, auf die folgende Kriterien zutreffen: + - Teilenr-Längen-Kombination existiert in beiden Stücklisten + - Teilenummer der Position ist in der Tabelle TMP_CODES_CASE_13 enthalten + + Hinweis: + Es reicht nicht aus, lediglich zu prüfen, ob die Teilenr-Längen-Kombination in beiden Stücklisten vorliegt + Grund: + Positionsnummern die Fall 1.1 zugeordnet werden können oder Positionsnummern, die unter Fall 1.2 fallen und deren Länge dabei in beiden + Stücklisten gleich bleibt würden grundlegend ebenfalls unter Fall 1.32 fallen und somit identifiziert werden. + Es gilt jedoch das Prioritätsprinzip, d.h. die Zuordnung zu Fall 1.1 oder Fall 1.2 erfolgt (sofern möglich) immer vor der Zuordnung + zu Fall 1.32! + +2. Zu den gefundenen Teilenummern folgende Spaltenwerte ermitteln und in die temporäre Tabelle TMP_POSNRS_CASE_132 schreiben: + - Teilenr des Parents + - Positionsnummer laut alter Stückliste + - Positionsnummer laut neuer Stückliste + + Hinweis: + - Die Positionsnummern aus beiden Stücklisten werden benötigt, um bei der Ermittlung der Update-Daten die Zuordnung zwischen der alten und neuen + Stückliste herstellen zu können + - Die Teilenummer des Parents wird zusamment mit der Positionsnummer laut alter Stückliste dafür benötigt, um in den Tabellen STKL_REGEL und + VAR_TEIL_BEDINGUNG_2 die Zeilen zu ermitteln, die aktualisiert werden müssen +*/ + +procedure get_case_132_positions(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select c.uebteilenr, + c.posnr as pos_alt, + rd.posnr as pos_neu + from k_sb_rd_comp rd + inner join comp c + on rd.uebteilenr = c.uebteilenr + and rd.kompteilenr = c.kompteilenr + and rd.laenge = coalesce(c.laenge, 0) + where rd.uebteilenr = i_uebteilenr + and rd.kompteilenr in (select kompteilenr from tmp_codes_case_13); +begin + delete from tmp_posnrs_case_132; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_posnrs_case_132 (uebteilenr, + pos_alt, + pos_neu) + values (xx_combined_bom.uebteilenr, + xx_combined_bom.pos_alt, + xx_combined_bom.pos_neu); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Ermittelt alle Positionsnummern, die entfernt werden sollen + +Hinweis: +Bei der Ermittlung dürfen die Positionsnummern, die verschoben werden NICHT berücksichtigt werden. Die alte Lösch-Logik: +"Die Teile die in der neuen Stückliste nicht drin sind, werden rausgelöscht" +ist daher nur noch eingeschränkt anwendbar! + +Grund: +Das liegt vor allem an Fall 1.2, denn per Definition darf in diesem Fall die Länge in der neuen Stückliste abweichen, solange alle +Teilenr-Posnr-Kombinationen in beiden Stücklisten identsich sind, siehe hierzu z.B. Pos. 3 in Beispiel 3 unter doc/Beispiele.pdf: +Dort liegt die Länge 200 aus der alten Stückliste nicht mehr in der neuen Stückliste vor. Pos. 3 würde also laut alter Logik gelöscht werden. +Da diese Positionsnummer aber unter Fall 1.2 fällt, wird sie in die neue Stückliste verschoben, darf also nicht gelöscht werden! +*/ + +procedure get_ids_to_delete(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select c.schluessel comp_schluessel, + b.uebteilenr bed_uebteilenr, + b.posnr bed_posnr, + b.varianten bed_varianten, + b.bed_gruppe bed_bed_gruppe, + b.pm bed_pm, + b.lfd_nr bed_lfd_nr, + r.uebteilenr regel_uebteilenr, + r.posnr regel_posnr, + r.varianten regel_varianten, + r.bed_gruppe regel_bed_gruppe + from comp c + left join (select uebteilenr, + pos_alt + from tmp_posnrs_case_11 + union + select uebteilenr, + pos_alt + from tmp_posnrs_case_12 + union + select uebteilenr, + pos_alt + from tmp_posnrs_case_132) cud + on c.uebteilenr = cud.uebteilenr + and c.posnr = cud.pos_alt + left join var_teil_bedingung_2 b + on c.uebteilenr = b.uebteilenr + and c.posnr = b.posnr + left join stkl_regel r + on c.uebteilenr = r.uebteilenr + and c.posnr = r.posnr + where c.uebteilenr = i_uebteilenr + and cud.uebteilenr is null; +begin + delete from tmp_ids_to_delete; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_ids_to_delete (comp_schluessel, + regel_uebteilenr, + regel_posnr, + regel_varianten, + regel_bed_gruppe, + bed_uebteilenr, + bed_posnr, + bed_varianten, + bed_bed_gruppe, + bed_pm, + bed_lfd_nr) + values (xx_combined_bom.comp_schluessel, + xx_combined_bom.regel_uebteilenr, + xx_combined_bom.regel_posnr, + xx_combined_bom.regel_varianten, + xx_combined_bom.regel_bed_gruppe, + xx_combined_bom.bed_uebteilenr, + xx_combined_bom.bed_posnr, + xx_combined_bom.bed_varianten, + xx_combined_bom.bed_bed_gruppe, + xx_combined_bom.bed_pm, + xx_combined_bom.bed_lfd_nr); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Ermittlung der neuen Stücklisteninformationen, mit denen die bestehenden Datzensätze überschrieben werden + +Die neuen Informationen werden für alle Positionsnummern bestimmt, die unter die Fälle 1.1, 1.2 und 1.32 fallen, +also die, die sich in den Tabellen TMP_POSNRS_CASE_11, TMP_POSNRS_CASE_12 & TMP_POSNRS_CASE_132 befinden. + +Hinweis: +Es werden in diesem Zuge auch die zugehörigen Zeilen-ID's zu den Positionsnummern in den Tabellen VAR_TEIL_BEDINGUNG_2 und STKL_REGEL ermittelt, +da in diesen Tabellen ebenfalls die Positionsnummern aktualisiert werden müssen, sofern welche vorliegen. Die Regeln und Bedingungen selbst +bleiben unverändert, da sie nur verschoben werden. +*/ + +procedure get_update_data(i_uebteilenr in comp.uebteilenr%type) is + + cursor c_combined_bom is + select c.schluessel comp_schluessel, + b.uebteilenr bed_uebteilenr, + b.posnr bed_posnr, + b.varianten bed_varianten, + b.bed_gruppe bed_bed_gruppe, + b.pm bed_pm, + b.lfd_nr bed_lfd_nr, + r.uebteilenr regel_uebteilenr, + r.posnr regel_posnr, + r.varianten regel_varianten, + r.bed_gruppe regel_bed_gruppe, + p.pos_alt, + rd.posnr pos_neu, + -- bestimmt wert für spalte 'ABW_ANZAHL': null, wenn pos. nicht längenabhängig, sonst wert 'Menge' aus csv + case + when rd.laenge = 0 then + null + else + rd.menge + end as abw_anzahl, + -- bestimmt wert für spalte 'MENGE': berechnung dezimalwert, wenn pos. längenabhängig, sonst wert 'Menge' aus csv + case + when rd.laenge = 0 then + rd.menge + else + rd.menge * (rd.laenge + coalesce(c.zuschnitt, 0)) / 1000 + end as menge, + -- bestimmt wert für spalte 'LAENGE': null, wenn pos. nicht längenabhängig, sonst wert 'Uebergabelaenge' aus csv + case + when rd.laenge = 0 then + null + else + rd.laenge + end as laenge, + c.zuschnitt, + c.dispo_aktiv_jn, + c.ruestcode + from (select uebteilenr, + pos_alt, + pos_neu + from tmp_posnrs_case_11 + union + select uebteilenr, + pos_alt, + pos_neu + from tmp_posnrs_case_12 + union + select uebteilenr, + pos_alt, + pos_neu + from tmp_posnrs_case_132) p + inner join comp c + on p.uebteilenr = c.uebteilenr + and p.pos_alt = c.posnr + inner join k_sb_rd_comp rd + on p.uebteilenr = rd.uebteilenr + and p.pos_neu = rd.posnr + left join var_teil_bedingung_2 b + on p.uebteilenr = b.uebteilenr + and p.pos_alt = b.posnr + left join stkl_regel r + on p.uebteilenr = r.uebteilenr + and p.pos_alt = r.posnr; +begin + delete from tmp_update_data; + + for xx_combined_bom in c_combined_bom loop + insert into tmp_update_data (comp_schluessel, + regel_uebteilenr, + regel_posnr, + regel_varianten, + regel_bed_gruppe, + bed_uebteilenr, + bed_posnr, + bed_varianten, + bed_bed_gruppe, + bed_pm, + bed_lfd_nr, + pos_alt, + pos_neu, + abw_anzahl, + menge, + laenge, + zuschnitt, + dispo_aktiv_jn, + ruestcode) + values (xx_combined_bom.comp_schluessel, + xx_combined_bom.regel_uebteilenr, + xx_combined_bom.regel_posnr, + xx_combined_bom.regel_varianten, + xx_combined_bom.regel_bed_gruppe, + xx_combined_bom.bed_uebteilenr, + xx_combined_bom.bed_posnr, + xx_combined_bom.bed_varianten, + xx_combined_bom.bed_bed_gruppe, + xx_combined_bom.bed_pm, + xx_combined_bom.bed_lfd_nr, + xx_combined_bom.pos_alt, + xx_combined_bom.pos_neu, + xx_combined_bom.abw_anzahl, + xx_combined_bom.menge, + xx_combined_bom.laenge, + xx_combined_bom.zuschnitt, + xx_combined_bom.dispo_aktiv_jn, + xx_combined_bom.ruestcode); + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +- Entfernt die Positionsnummern aus COMP, die nicht mehr in der neuen Stückliste vorliegen +- Entfernt die TOS-Regeln und -Bedingungen der Positionsnummern aus VAR_TEIL_BEDINGUNG_2 und STKL_REGEL +*/ + + +procedure do_delete is +begin + + delete from comp where schluessel in (select comp_schluessel from tmp_ids_to_delete); + + delete from var_teil_bedingung_2 + where (uebteilenr, + posnr, + varianten, + bed_gruppe, + pm, + lfd_nr) in (select bed_uebteilenr, + bed_posnr, + bed_varianten, + bed_bed_gruppe, + bed_pm, + bed_lfd_nr + from tmp_ids_to_delete); + + delete from stkl_regel + where (uebteilenr, + posnr, + varianten, + bed_gruppe) in (select regel_uebteilenr, + regel_posnr, + regel_varianten, + regel_bed_gruppe + from tmp_ids_to_delete); +end; + +-------------------------------------------------------------------------------------------- + +/* +Neuanlage aller Positionen, die nur in der neuen Stückliste vorliegen (das sind die aus der Tabelle TMP_POSNRS_CASE_131) + +Hinweise: +- Neue Positionen werden immer ohne TOS-Regeln oder -Bedingungen angelegt, d.h. es erfolgen keine INSERT-Statements + in den Tabellen VAR_TEIL_BEDINGUNG_2 oder STKL_REGEL! +- Zur Verdeutlichung, welche Werte z.B. in der Spalte Ruestcode oder Dispoaktiv nach der Neuanlage vorliegen, werden + die Defaultwerte aus der PARTS-Tabelle geholt. Ob ein solcher INSERT auch in SIVAS erforderlich ist, war zum Zeitpunkt + der Erstellung dieses Scripts nicht klar. +*/ + +procedure do_insert(i_uebteilenr in comp.uebteilenr%type) is + cursor c_comp is + select rd.uebteilenr, + rd.posnr as posnr, + rd.kompteilenr, + -- bestimmt wert für spalte 'ABW_ANZAHL': null, wenn pos. nicht längenabhängig, sonst wert 'Menge' aus csv + case + when rd.laenge = 0 then + null + else + rd.menge + end as abw_anzahl, + -- bestimmt wert für spalte 'MENGE': berechnung dezimalwert, wenn pos. längenabhängig, sonst wert 'Menge' aus csv + case + when rd.laenge = 0 then + rd.menge + else + rd.menge * (rd.laenge + coalesce(c.zuschnitt, 0)) / 1000 + end as menge, + -- bestimmt wert für spalte 'LAENGE': null, wenn pos. nicht längenabhängig, sonst wert 'Uebergabelaenge' aus csv + case + when rd.laenge = 0 then + null + else + rd.laenge + end as laenge, + null as zuschnitt, + p.dispo_aktiv_jn, + p.ruestcode + from k_sb_rd_comp rd + left join comp c + on rd.kompteilenr = c.kompteilenr + and rd.laenge = coalesce(c.laenge, 0) + and rd.uebteilenr = c.uebteilenr + left join parts p + on rd.kompteilenr = p.teilenr + where c.kompteilenr is null + and rd.uebteilenr = i_uebteilenr + and rd.posnr in (select posnr from tmp_posnrs_case_131); + + x_posnr comp.posnr%type; + x_varianten comp.varianten%type; + x_menge number; + x_meldung varchar2(4000); + +begin + for xx_comp in c_comp loop + + x_posnr := xx_comp.posnr; + x_varianten := 0; + x_menge := xx_comp.menge; + + if not objekt_anlage.comp_anlegen(i_uebteilenr => xx_comp.uebteilenr, + io_posnr => x_posnr, + io_varianten => x_varianten, + i_kompteilenr => xx_comp.kompteilenr, + io_menge => x_menge, + i_abw_anzahl => xx_comp.abw_anzahl, + i_laenge => xx_comp.laenge, + o_meldung => x_meldung, + i_protok => 'N') then + -- Fehler + null; + else + update comp c + set c.zuschnitt = xx_comp.zuschnitt, + c.ruestcode = xx_comp.ruestcode, + c.dispo_aktiv_jn = xx_comp.dispo_aktiv_jn + where c.uebteilenr = xx_comp.uebteilenr + and c.posnr * -1 = x_posnr + and c.varianten = x_varianten; + end if; + end loop; +end; + +-------------------------------------------------------------------------------------------- + +/* +Aktualisiert die Positionsnummern, deren Spaltenanpassungen und TOS-Regeln / -Bedingungen von der alten in die neue Stückliste übernommen werden sollen. +*/ + +procedure do_update(i_uebteilenr in comp.uebteilenr%type) is + cursor c_data is + select ud.comp_schluessel, + ud.pos_neu, + ud.abw_anzahl, + ud.menge, + ud.laenge, + ud.zuschnitt, + ud.dispo_aktiv_jn, + ud.ruestcode, + ud.bed_uebteilenr, + ud.bed_posnr, + ud.bed_varianten, + ud.bed_bed_gruppe, + ud.bed_pm, + ud.bed_lfd_nr, + ud.regel_uebteilenr, + ud.regel_posnr, + ud.regel_varianten, + ud.regel_bed_gruppe + from tmp_update_data ud; + + x_key_uebteilenr varchar2(4000); + x_key_posnr varchar2(4000); + x_key_varianten varchar2(4000); + x_key_manu varchar2(4000); + x_key_feld5 varchar2(4000); + x_key_feld6 varchar2(4000); + x_key_feld7 varchar2(4000); + x_key_feld8 varchar2(4000); + x_key_feld9 varchar2(4000); + +begin + for xx_data in c_data loop + + x_key_uebteilenr := null; + x_key_posnr := null; + x_key_varianten := null; + x_key_manu := null; + + if not schluessel.umdrehen(i_schluessel => xx_data.comp_schluessel, + i_tabelle => 'COMP', + o_feld_1 => x_key_uebteilenr, + o_feld_2 => x_key_posnr, + o_feld_3 => x_key_varianten, + o_feld_4 => x_key_manu, + o_feld_5 => x_key_feld5, + o_feld_6 => x_key_feld6, + o_feld_7 => x_key_feld7, + o_feld_8 => x_key_feld8, + o_feld_9 => x_key_feld9, + i_protok => 'N') then + -- Fehler + return; + end if; + + x_key_posnr := x_key_posnr * -1; + + update comp c + set c.posnr = xx_data.pos_neu, + c.abw_anzahl = xx_data.abw_anzahl, + c.menge = xx_data.menge, + c.laenge = xx_data.laenge, + c.zuschnitt = xx_data.zuschnitt, + c.dispo_aktiv_jn = xx_data.dispo_aktiv_jn, + c.ruestcode = xx_data.ruestcode + where c.uebteilenr = x_key_uebteilenr + and c.posnr = x_key_posnr + and c.varianten = x_key_varianten + and c.manu = x_key_manu; + + update var_teil_bedingung_2 v + set posnr = xx_data.pos_neu + where v.uebteilenr = xx_data.bed_uebteilenr + and v.posnr = xx_data.bed_posnr + and v.varianten = xx_data.bed_varianten + and v.bed_gruppe = xx_data.bed_bed_gruppe + and v.pm = xx_data.bed_pm + and v.lfd_nr = xx_data.bed_lfd_nr; + + update stkl_regel r + set posnr = xx_data.pos_neu + where r.uebteilenr = x_key_uebteilenr + and r.posnr = x_key_posnr + and r.varianten = x_key_varianten + and r.bed_gruppe = xx_data.regel_bed_gruppe; + end loop; +end; + +-------------------------------------------------------------------------------------------- + +procedure cleanup(i_uebteilenr in comp.uebteilenr%type) is + +begin + delete from tmp_codes_case_12_or_13; + delete from tmp_codes_case_13; + delete from tmp_posnrs_case_11; + delete from tmp_posnrs_case_12; + delete from tmp_posnrs_case_131; + delete from tmp_posnrs_case_132; + delete from tmp_ids_to_delete; + delete from tmp_update_data; + + delete from stkl_regel r + where r.uebteilenr = i_uebteilenr + and r.posnr < 0 + and exists (select 1 + from stkl_regel rr + where rr.uebteilenr = r.uebteilenr + and rr.posnr = r.posnr * -1); + + update stkl_regel r + set posnr = posnr * -1 + where uebteilenr = i_uebteilenr + and posnr < 0; + + delete from comp c + where c.uebteilenr = i_uebteilenr + and c.posnr < 0 + and exists (select 1 + from comp cc + where cc.uebteilenr = c.uebteilenr + and cc.posnr = c.posnr * -1); + + update comp c + set posnr = posnr * -1 + where uebteilenr = i_uebteilenr + and posnr < 0; +end; + +-------------------------------------------------------------------------------------------- + +function insert_csv_data(i_datei_name in varchar2, + o_uebteilenr out comp.uebteilenr%type, + o_meldung out varchar2) return boolean is + xx_comp k_sb_rd_comp%rowtype := null; + x_file utl_file.file_type; + x_zeile varchar2(4000); + x_text varchar2(4000); + x_header_zeile boolean := true; + + x_anz_spalten number := 5; + x_spalte number := 1; + x_spalte_uebteilenr number := 1; + x_spalte_posnr number := 2; + x_spalte_kompteilenr number := 3; + x_spalte_menge number := 4; + x_spalte_laenge number := 5; + + x_menge number; + + cursor c_werte(ic_zeile varchar) is + select lvl, + replace(regexp_substr(ic_zeile, '[^;]*;?', 1, lvl), ';') wert, + count(*) over () anz + from dual cross apply (select level lvl + from dual + connect by level <= regexp_count(ic_zeile, ';') + 1); + + cursor c_parts(ic_teilenr comp.kompteilenr%type) is + select nvl(p.abw_anzahl_jn, 'N') abw_anzahl_jn, + p.teilenr, + nvl(p.kzkauf, 'K') kzkauf + from parts p + where p.teilenr = ic_teilenr; + xx_parts c_parts%rowtype; + + cursor c_posnr_doppelt(ic_uebteilenr comp.uebteilenr%type, + ic_posnr comp.posnr%type) is + select posnr + from k_sb_rd_comp + where uebteilenr = ic_uebteilenr + and posnr = ic_posnr; + x_posnr_doppelt k_sb_rd_comp.posnr%type; +begin + + delete from k_sb_rd_comp; + + -- Datei einlesen + x_file := sivas_utl_file.fopen(location => 'K_RD_TO_SIVAS_COMP_WORK', + filename => i_datei_name, + open_mode => 'R'); + + loop + + begin + sivas_utl_file.get_line(x_file, x_zeile); + exception + when no_data_found then + exit; + when others then + return true; + end; + + if true then + x_text := convert(x_zeile, 'WE8ISO8859P15', 'UTF8'); + else + x_text := x_zeile; + end if; + + if x_header_zeile then + x_header_zeile := false; + continue; + end if; + + xx_comp := null; + x_spalte := 1; + for xx_werte in c_werte(x_text) loop + if xx_werte.anz != x_anz_spalten then + sivas_utl_file.fclose(x_file); + return true; + end if; + + if x_spalte = x_spalte_uebteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + return true; + end if; + + open c_parts(trim(xx_werte.wert)); + fetch c_parts into xx_parts; + close c_parts; + + if xx_parts.teilenr is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + + xx_comp.uebteilenr := trim(xx_werte.wert); + o_uebteilenr := xx_comp.uebteilenr; + + elsif x_spalte = x_spalte_posnr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + return true; + end if; + xx_comp.posnr := to_number(xx_werte.wert) * 10; + + elsif x_spalte = x_spalte_kompteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + return true; + end if; + xx_comp.kompteilenr := trim(xx_werte.wert); + + elsif x_spalte = x_spalte_menge then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + return true; + end if; + + x_menge := to_number(trim(xx_werte.wert)); + xx_comp.menge := x_menge; + elsif x_spalte = x_spalte_laenge and trim(xx_werte.wert) is not null then + xx_comp.laenge := rd_to_number(xx_werte.wert); + end if; + + x_spalte := x_spalte + 1; + end loop; + + open c_posnr_doppelt(xx_comp.uebteilenr, xx_comp.posnr); + fetch c_posnr_doppelt into x_posnr_doppelt; + close c_posnr_doppelt; + + if x_posnr_doppelt is not null then + o_meldung := 'Die Position ' || xx_comp.posnr || ' kommt mehrfach in der Import-Datei vor.'; + sivas_utl_file.fclose(x_file); + return false; + end if; + + insert into k_sb_rd_comp(uebteilenr, + posnr, + kompteilenr, + laenge, + menge) + values (xx_comp.uebteilenr, + xx_comp.posnr, + xx_comp.kompteilenr, + xx_comp.laenge, + xx_comp.menge); + + end loop; + + if o_uebteilenr is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + + sivas_utl_file.fclose(x_file); + return true; +end; + +-------------------------------------------------------------------------------------------- + +function tmp_tabelle_fuellen(i_datei_name in varchar2, + i_pfad in file_beschreibung.file_pfad%type, + o_meldung out varchar2) return boolean is + xx_comp k_sb_rd_comp%rowtype := null; + x_file utl_file.file_type; + x_zeile varchar2(4000); + x_text varchar2(4000); + x_header_zeile boolean := true; + + x_anz_spalten number := 5; + x_spalte number := 1; + x_spalte_uebteilenr number := 1; + x_spalte_posnr number := 2; + x_spalte_kompteilenr number := 3; + x_spalte_menge number := 4; + x_spalte_laenge number := 5; + + x_menge number; + x_uebteilenr comp.uebteilenr%type; + + cursor c_werte(ic_zeile varchar) is + select lvl, + replace(regexp_substr(ic_zeile, '[^;]*;?', 1, lvl), ';') wert, + count(*) over () anz + from dual cross apply (select level lvl + from dual + connect by level <= regexp_count(ic_zeile, ';') + 1); + + cursor c_parts(ic_teilenr comp.kompteilenr%type) is + select nvl(p.abw_anzahl_jn, 'N') abw_anzahl_jn, + p.teilenr, + nvl(p.kzkauf, 'K') kzkauf + from parts p + where p.teilenr = ic_teilenr; + xx_parts c_parts%rowtype; + + cursor c_posnr_doppelt(ic_uebteilenr comp.uebteilenr%type, + ic_posnr comp.posnr%type) is + select posnr + from k_sb_rd_comp + where uebteilenr = ic_uebteilenr + and posnr = ic_posnr; + x_posnr_doppelt k_sb_rd_comp.posnr%type; + + cursor c_teil_quelle is + select distinct t.kompteilenr + from k_sb_rd_comp t + where t.uebteilenr = x_uebteilenr + and nvl(t.laenge, 0) != 0; + + cursor c_laenge(ic_kompteilenr k_sb_rd_comp.kompteilenr%type) is + select t.laenge, + -- t.posnr * 10 posnr, + count(1) anz + from k_sb_rd_comp t + where t.kompteilenr = ic_kompteilenr + and t.uebteilenr = x_uebteilenr + group by t.laenge; + + cursor c_laenge_einzeln(ic_kompteilenr k_sb_rd_comp.kompteilenr%type) is + select t.laenge, + t.posnr * 10 posnr, + count(1) anz + from k_sb_rd_comp t + where t.kompteilenr = ic_kompteilenr + and t.uebteilenr = x_uebteilenr + group by t.laenge, + t.posnr; + + cursor c_laeng_vorh_quelle is + select c.posnr * 10 posnr + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0; + x_laeng_vorh_quelle comp.posnr%type; + + cursor c_laenge_quelle(ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type) is + select c.kompteilenr, + nvl(c.laenge, 0) laenge + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr + and c.kompteilenr = ic_kompteilenr + and nvl(c.laenge, 0) = nvl(ic_laenge, 0); + xx_laenge_quelle c_laenge_quelle%rowtype; + + cursor c_laenge_ziel is + select c.kompteilenr, + nvl(c.laenge, 0) laenge + from comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0; + + cursor c_laeng_vorh_ziel is + select c.posnr + from comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0; + x_laeng_vorh_ziel comp.posnr%type; + + x_fortfahren_1 boolean := false; + + cursor c_anz_ziel(ic_kompteilenr k_sb_rd_comp.kompteilenr%type, + ic_laenge k_sb_rd_comp.laenge%type) is + select count(1) anz + from comp c + where c.uebteilenr = x_uebteilenr + and c.kompteilenr = ic_kompteilenr + and c.laenge = ic_laenge; + x_anz_ziel number; + + cursor c_comp_ziel(ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type) is + select c.posnr, + c.varianten + from comp c + where c.uebteilenr = x_uebteilenr + and c.kompteilenr = ic_kompteilenr + and c.laenge = ic_laenge; + xx_comp_ziel c_comp_ziel%rowtype; + + cursor c_fall_2 is + select c.posnr, + c.kompteilenr, + c.laenge laenge_alt, + k.laenge laenge_neu, + nvl(c.abw_anzahl, 0) abw_anzahl, + nvl(c.zuschnitt, 0) zuschnitt, + nvl(k.menge, 0) menge_neu, + nvl(p.abw_anzahl_jn, 'N') abw_anzahl_jn + from comp c, + k_sb_rd_comp k, + parts p + where nvl(k.ignorieren_jn, 'N') != 'J' + and c.uebteilenr = k.uebteilenr + and c.kompteilenr = k.kompteilenr + and c.posnr = k.posnr * 10 + and p.teilenr = k.kompteilenr + and nvl(c.laenge, 0) != nvl(k.laenge, 0); + x_fall2_menge comp.menge%type; + x_fall2_abw_anz comp.abw_anzahl%type; + + cursor c_wf_notif_av is + select listagg('Pos.' || c.posnr || ' – ' || c.kompteilenr, ', ') within group (order by c.posnr) text + from parts p, + comp c + where c.uebteilenr = x_uebteilenr + and p.teilenr = c.kompteilenr + and nvl(p.info2_jn, 'N') != 'J' + and (nvl(c.ruestcode, 'X') != nvl(p.ruestcode, 'N') or + nvl(c.dispo_aktiv_jn, 'N') != 'J' or + c.zuschnitt is not null); + xx_wf_notif_av c_wf_notif_av%rowtype; + + cursor c_laeng_pruef_quell is + select c.posnr * 10 posnr, + c.laenge + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0 + order by c.posnr; + + cursor c_laeng_pruef_ziel(ic_posnr k_sb_rd_comp.posnr%type) is + select nvl(c.laenge, 0) laenge + from comp c + where c.uebteilenr = x_uebteilenr + and c.posnr = ic_posnr; + x_laeng_pruef_ziel comp.laenge%type; + + cursor c_wf_av_quell_cnt is + select count(1) anz + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr; + x_wf_av_quell_cnt number; + + cursor c_wf_av_ziel_cnt is + select count(1) anz + from comp c + where c.uebteilenr = x_uebteilenr; + x_wf_av_ziel_cnt number; + + cursor c_wf_av_quell_tnr is + select kompteilenr + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr; + x_wf_av_quell_tnr k_sb_rd_comp.kompteilenr%type; + + cursor c_wf_av_ziel_tnr is + select kompteilenr + from comp c + where c.uebteilenr = x_uebteilenr; + x_wf_av_ziel_tnr comp.kompteilenr%type; + + cursor c_wf_notif_tos is + select listagg('Pos.' || c.posnr || ' – ' || c.kompteilenr, ', ') within group (order by c.posnr) text + from comp c + where uebteilenr = x_uebteilenr + and (exists (select 1 from var_teil_bedingung_2 t where t.uebteilenr = c.uebteilenr and t.posnr = c.posnr) or + exists (select 1 from stkl_regel t where t.uebteilenr = c.uebteilenr and t.posnr = c.posnr)); + xx_wf_notif_tos c_wf_notif_tos%rowtype; + + cursor c_bsp_6_ziel is + select posnr, + kompteilenr, + laenge, + count(1) over () anz + from comp + where uebteilenr = x_uebteilenr + and nvl(laenge, 0) != 0; + xx_bsp_6_ziel c_bsp_6_ziel%rowtype; + + cursor c_bsp_6_csv is + select posnr * 10 posnr, + kompteilenr, + laenge, + count(1) over () anz + from k_sb_rd_comp + where uebteilenr = x_uebteilenr + and nvl(laenge, 0) != 0; + xx_bsp_6_csv c_bsp_6_csv%rowtype; + + cursor c_bsp_12_anz_teilenr is + select count(1) over() anz + from k_sb_rd_comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0 + group by c.kompteilenr; + x_bsp_12_anz_teilenr number; + + x_fall_1_angewendet boolean := false; + x_fall_2_anwenden boolean := false; + + x_wf_meldung_av_pre boolean := true; + x_wf_meldung_av boolean := true; +begin + + delete from k_sb_rd_comp; + + -- Datei einlesen + x_file := sivas_utl_file.fopen(location => 'K_RD_TO_SIVAS_COMP_WORK', + filename => i_datei_name, + open_mode => 'R'); + + loop + + begin + sivas_utl_file.get_line(x_file, x_zeile); + exception + when no_data_found then + exit; + when others then + return true; + end; + + if true then + x_text := convert(x_zeile, 'WE8ISO8859P15', 'UTF8'); + else + x_text := x_zeile; + end if; + + if x_header_zeile then + x_header_zeile := false; + continue; + end if; + + xx_comp := null; + x_spalte := 1; + for xx_werte in c_werte(x_text) loop + if xx_werte.anz != x_anz_spalten then + sivas_utl_file.fclose(x_file); + return true; + end if; + + if x_spalte = x_spalte_uebteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + return true; + end if; + + open c_parts(trim(xx_werte.wert)); + fetch c_parts into xx_parts; + close c_parts; + + if xx_parts.teilenr is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + + xx_comp.uebteilenr := trim(xx_werte.wert); + x_uebteilenr := xx_comp.uebteilenr; + + elsif x_spalte = x_spalte_posnr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + return true; + end if; + xx_comp.posnr := to_number(xx_werte.wert); + + elsif x_spalte = x_spalte_kompteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + return true; + end if; + xx_comp.kompteilenr := trim(xx_werte.wert); + + elsif x_spalte = x_spalte_menge then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + return true; + end if; + + x_menge := to_number(trim(xx_werte.wert)); + xx_comp.menge := x_menge; + elsif x_spalte = x_spalte_laenge and trim(xx_werte.wert) is not null then + xx_comp.laenge := rd_to_number(xx_werte.wert); + end if; + + x_spalte := x_spalte + 1; + end loop; + + open c_posnr_doppelt(xx_comp.uebteilenr, xx_comp.posnr); + fetch c_posnr_doppelt into x_posnr_doppelt; + close c_posnr_doppelt; + + if x_posnr_doppelt is not null then + o_meldung := 'Die Position ' || xx_comp.posnr || ' kommt mehrfach in der Import-Datei vor.'; + sivas_utl_file.fclose(x_file); + return false; + end if; + + insert into k_sb_rd_comp(uebteilenr, + posnr, + kompteilenr, + laenge, + menge) + values (xx_comp.uebteilenr, + xx_comp.posnr, + xx_comp.kompteilenr, + xx_comp.laenge, + xx_comp.menge); + + end loop; + + if x_uebteilenr is null then + sivas_utl_file.fclose(x_file); + return true; + end if; + + open c_wf_notif_tos; + fetch c_wf_notif_tos into xx_wf_notif_tos; + close c_wf_notif_tos; + + if xx_wf_notif_tos.text is not null then + rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_tos => 'Bitte Stückliste ' || x_uebteilenr || ' prüfen. Vor der Änderung lagen bei folgenden Positionen TOS-Regeln oder -Bedingungen vor: ' || xx_wf_notif_tos.text); + end if; + + x_wf_meldung_av_pre := true; + x_wf_meldung_av := false; + + -- Wenn auf beiden Seite nur 1 Position + -- dann pruefen ob die Teilenummern ungleich sind + -- ist das der Fall, dann soll keine WF-Meldung an die AV erfolgen + open c_wf_av_quell_cnt; + fetch c_wf_av_quell_cnt into x_wf_av_quell_cnt; + close c_wf_av_quell_cnt; + + open c_wf_av_ziel_cnt; + fetch c_wf_av_ziel_cnt into x_wf_av_ziel_cnt; + close c_wf_av_ziel_cnt; + + if nvl(x_wf_av_quell_cnt, 0) = nvl(x_wf_av_ziel_cnt, 0) and nvl(x_wf_av_ziel_cnt, 0) = 1 then + open c_wf_av_quell_tnr; + fetch c_wf_av_quell_tnr into x_wf_av_quell_tnr; + close c_wf_av_quell_tnr; + + open c_wf_av_ziel_tnr; + fetch c_wf_av_ziel_tnr into x_wf_av_ziel_tnr; + close c_wf_av_ziel_tnr; + + if nvl(x_wf_av_quell_tnr, 'XY') != nvl(x_wf_av_ziel_tnr, 'XY') then + x_wf_meldung_av_pre := false; + end if; + end if; + + + -- Prüfen ob in beiden Stücklisten >= 1 Längenvarianten vorliegen + if x_wf_meldung_av_pre then + open c_laeng_vorh_quelle; + fetch c_laeng_vorh_quelle into x_laeng_vorh_quelle; + close c_laeng_vorh_quelle; + + if x_laeng_vorh_quelle is not null then + + open c_laeng_vorh_ziel; + fetch c_laeng_vorh_ziel into x_laeng_vorh_ziel; + close c_laeng_vorh_ziel; + + if x_laeng_vorh_ziel is not null then + -- Prüfen ob nicht alle Längenvarianten aus der alten Stückliste in der neuen Stückliste vorliegen + for xx_laenge_ziel in c_laenge_ziel loop + + xx_laenge_quelle.kompteilenr := null; + open c_laenge_quelle(xx_laenge_ziel.kompteilenr, + xx_laenge_ziel.laenge); + fetch c_laenge_quelle into xx_laenge_quelle; + close c_laenge_quelle; + + if xx_laenge_quelle.kompteilenr is null then + x_wf_meldung_av := true; + exit; + end if; + + end loop; + end if; + else + x_wf_meldung_av := false; + end if; + end if; + + if x_wf_meldung_av then + open c_wf_notif_av; + fetch c_wf_notif_av into xx_wf_notif_av; + close c_wf_notif_av; + + if xx_wf_notif_av.text is not null then + rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_av => 'Bitte Stückliste ' || x_uebteilenr || ' prüfen. Vor der Änderung lagen bei folgenden Positionen manuelle Eintragungen / Änderungen in den Spalten ''Zuschnitt'', ''Rüstcode'' oder ''Dispoaktiv'' vor: ' || xx_wf_notif_av.text); + end if; + end if; + + -- Pruefung Beispiel 6 + -- Wenn weder Bsp 4 noch Bsp 4 zieht, dann soll nachgelagerte Logik ziehen. + -- D.h.: Wenn es auf beiden Seiten Längenvarianten gibt, jedoch + -- unterschiedliche Anzahl an Längenvarianten und + -- die Längenvarianten unterschiedliche Positionsnummern haben + open c_bsp_6_ziel; + fetch c_bsp_6_ziel into xx_bsp_6_ziel; + close c_bsp_6_ziel; + + open c_bsp_6_csv; + fetch c_bsp_6_csv into xx_bsp_6_csv; + close c_bsp_6_csv; + + if nvl(xx_bsp_6_ziel.anz, 0) > 0 and nvl(xx_bsp_6_csv.anz, 0) > 0 and + nvl(xx_bsp_6_ziel.anz, 0) != nvl(xx_bsp_6_csv.anz, 0) then + for xx_bsp_6_ziel_loop in c_bsp_6_ziel loop + for xx_bsp_6_csv_loop in c_bsp_6_csv loop + if xx_bsp_6_ziel_loop.kompteilenr = xx_bsp_6_csv_loop.kompteilenr and + xx_bsp_6_ziel_loop.laenge = xx_bsp_6_csv_loop.laenge and + xx_bsp_6_ziel_loop.posnr != xx_bsp_6_csv_loop.posnr then + -- Beispiel 6 trifft ein -> nachgelagerte (alte) Logik muss ziehen + sivas_utl_file.fclose(x_file); + return true; + end if; + end loop; + end loop; + end if; + + -- Prüfen ob die Anzahl der Kombination KOMPTEILENR + LAENGE in Quelle und Ziel gleich sind, wenn ja, + -- erhalten die Positionen mit der matchenden Kombination die neue Positionsnummer mal 10 und der Datensatz + -- erhält den Haken IGNORIEREN_JN = 'J' + x_fortfahren_1 := false; + for xx_teil_quelle in c_teil_quelle loop + for xx_laenge in c_laenge(xx_teil_quelle.kompteilenr) loop + if nvl(xx_laenge.anz, 0) != 1 then -- Wenn eine Laenge mehr als 1x vorkommt ist das nicht der Fall der hier behandelt wird + x_fortfahren_1 := true; + exit; + end if; + + open c_anz_ziel(xx_teil_quelle.kompteilenr, xx_laenge.laenge); + fetch c_anz_ziel into x_anz_ziel; + close c_anz_ziel; + + if nvl(x_anz_ziel, 0) != 1 then + x_fortfahren_1 := true; -- Wenn die Anzahl im Ziel ungleich der Quelle dann wird das nicht hier abgearbeitet (anderer Fall) + exit; + end if; + end loop; + + if x_fortfahren_1 then + exit; + end if; + end loop; + + if not x_fortfahren_1 then + -- Update der Positionen von Bedingungen / Regeln und COMP-Saetzen + for xx_teil_quelle in c_teil_quelle loop + for xx_laenge in c_laenge_einzeln(xx_teil_quelle.kompteilenr) loop + xx_comp_ziel.posnr := null; + open c_comp_ziel(xx_teil_quelle.kompteilenr, xx_laenge.laenge); + fetch c_comp_ziel into xx_comp_ziel; + close c_comp_ziel; + + if xx_comp_ziel.posnr is null then + exit; + end if; + + if not stkl_verschieben.comp_zu_comp(i_quell_teilenr => x_uebteilenr, + i_quell_posnr => xx_comp_ziel.posnr, + i_quell_varianten => xx_comp_ziel.varianten, + i_ziel_teilenr => x_uebteilenr, + i_ziel_posnr => xx_comp_ziel.posnr * -1, + i_ziel_varianten => xx_comp_ziel.varianten, + o_msg => o_meldung, + i_protok => 'N') then + exit; + end if; + end loop; + end loop; + + for xx_teil_quelle in c_teil_quelle loop + for xx_laenge in c_laenge_einzeln(xx_teil_quelle.kompteilenr) loop + xx_comp_ziel.posnr := null; + open c_comp_ziel(xx_teil_quelle.kompteilenr, xx_laenge.laenge); + fetch c_comp_ziel into xx_comp_ziel; + close c_comp_ziel; + + if xx_comp_ziel.posnr is null then + exit; + end if; + + if not stkl_verschieben.comp_zu_comp(i_quell_teilenr => x_uebteilenr, + i_quell_posnr => xx_comp_ziel.posnr, + i_quell_varianten => xx_comp_ziel.varianten, + i_ziel_teilenr => x_uebteilenr, + i_ziel_posnr => xx_laenge.posnr, + i_ziel_varianten => xx_comp_ziel.varianten, + o_msg => o_meldung, + i_protok => 'N') then + exit; + end if; + + update k_sb_rd_comp k + set k.ignorieren_jn = 'J' + where k.uebteilenr = x_uebteilenr + and k.kompteilenr = xx_teil_quelle.kompteilenr + and k.laenge = xx_laenge.laenge + and k.posnr = xx_laenge.posnr / 10; + + /*rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_tos => 'Bei der Stückliste ' || x_uebteilenr || ' wurde die längenabhängige Position ' || x_posnr_ziel || ' zu Position ' || xx_laenge.posnr || ' getauscht.');*/ + + if not x_fall_1_angewendet then + x_fall_1_angewendet := true; + end if; + end loop; + end loop; + end if; + + delete from var_teil_bedingung_2 where uebteilenr = x_uebteilenr and posnr < 0; + delete from stkl_regel where uebteilenr = x_uebteilenr and posnr < 0; + delete from comp where uebteilenr = x_uebteilenr and posnr < 0; + + if x_fall_1_angewendet then + sivas_utl_file.fclose(x_file); + return true; + end if; + + -- Hier vorher pruefen ob jedes Position auf beiden Seiten auch eine Laenge hat + + open c_bsp_12_anz_teilenr; + fetch c_bsp_12_anz_teilenr into x_bsp_12_anz_teilenr; + close c_bsp_12_anz_teilenr; + + if nvl(x_bsp_12_anz_teilenr, 0) = 1 then + for xx_laeng_pruef_quell in c_laeng_pruef_quell loop + x_laeng_pruef_ziel := null; + open c_laeng_pruef_ziel(xx_laeng_pruef_quell.posnr); + fetch c_laeng_pruef_ziel into x_laeng_pruef_ziel; + close c_laeng_pruef_ziel; + + -- Wenn es an einer korrespondierenden Position keine Länge gibt, wird Fall 2 nicht angewendet. + if nvl(x_laeng_pruef_ziel, 0) = 0 then + sivas_utl_file.fclose(x_file); + return true; + end if; + end loop; + else + x_fall_2_anwenden := false; + + for xx_laeng_pruef_quell in c_laeng_pruef_quell loop + x_laeng_pruef_ziel := null; + open c_laeng_pruef_ziel(xx_laeng_pruef_quell.posnr); + fetch c_laeng_pruef_ziel into x_laeng_pruef_ziel; + close c_laeng_pruef_ziel; + + -- Wenn es an einer korrespondierenden Position keine Länge gibt, wird Fall 2 nicht angewendet. + if nvl(x_laeng_pruef_ziel, 0) = 0 then + null; + else + x_fall_2_anwenden := true; + exit; + end if; + end loop; + + if not x_fall_2_anwenden then + sivas_utl_file.fclose(x_file); + return true; + end if; + end if; + + -- Über alle laengenabhaengige Teile iterieren, wo die Posnr gleich geblieben ist, aber + -- die Laenge geandert werden muss + for xx_fall_2 in c_fall_2 loop + if xx_fall_2.abw_anzahl_jn = 'J' then + x_fall2_menge := xx_fall_2.menge_neu * ( ( nvl(xx_fall_2.laenge_neu, 0) / 1000 ) + ( xx_fall_2.zuschnitt / 1000 ) ); + x_fall2_abw_anz := xx_fall_2.menge_neu; + else + x_fall2_menge := xx_fall_2.menge_neu; + x_fall2_abw_anz := null; + end if; + + update comp c + set c.laenge = xx_fall_2.laenge_neu, + c.menge = x_fall2_menge, + c.abw_anzahl = x_fall2_abw_anz + where c.uebteilenr = x_uebteilenr + and c.kompteilenr = xx_fall_2.kompteilenr + and c.laenge = xx_fall_2.laenge_alt + and c.posnr = xx_fall_2.posnr; + + update k_sb_rd_comp k + set k.ignorieren_jn = 'J' + where k.uebteilenr = x_uebteilenr + and k.kompteilenr = xx_fall_2.kompteilenr + and k.laenge = xx_fall_2.laenge_neu + and k.posnr = xx_fall_2.posnr / 10; + + /*rd_protok(i_kontext => 'COMP', + i_pfad => i_pfad, + i_meldung_tos => 'Bei der Stückliste ' || x_uebteilenr || ' wurde die Länge der längenabhängigen Position ' || x_posnr_ziel || ' von ' || xx_fall_2.laenge_alt || ' zu ' || xx_fall_2.laenge_neu || ' geändert.', + i_meldung_av => 'Bei der Stückliste ' || x_uebteilenr || ' wurde die Länge der längenabhängigen Position ' || x_posnr_ziel || ' von ' || xx_fall_2.laenge_alt || ' zu ' || xx_fall_2.laenge_neu || ' geändert.'); */ + end loop; + + sivas_utl_file.fclose(x_file); + return true; +end; + +-------------------------------------------------------------------------------------------- + +function import_comp_alt(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean is + x_datei_name varchar2(500) := substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1); + x_verzeichnis varchar2(2000) := substr(i_voller_pfad, 1, instr(i_voller_pfad, '/', -1)); + x_work_dir varchar2(2000) := x_verzeichnis || 'work/'; + + x_file utl_file.file_type; + x_zeile varchar2(4000); + x_text varchar2(4000); + x_header_zeile boolean := true; + x_erstes_mal boolean := true; + x_meldung varchar2(4000); + + x_uebteilenr comp.uebteilenr%type; + + cursor c_parts(ic_teilenr comp.kompteilenr%type) is + select nvl(p.abw_anzahl_jn, 'N') abw_anzahl_jn, + p.teilenr, + nvl(p.kzkauf, 'K') kzkauf + from parts p + where p.teilenr = ic_teilenr; + xx_parts c_parts%rowtype; + + cursor c_beist_vorh(ic_teilenr comp.uebteilenr%type) is + select c.kompteilenr + from comp c + where c.uebteilenr = ic_teilenr + and nvl(c.kz_lieferanten_beistellung, 'N') = 'J'; + x_beist_vorh comp.kompteilenr%type; + + cursor c_comp_exists(ic_teilenr comp.uebteilenr%type) is + select c.kompteilenr + from comp c + where c.uebteilenr = ic_teilenr; + x_comp_exists comp.kompteilenr%type; + + cursor c_pos_im_ziel(ic_uebteilenr comp.uebteilenr%type, + ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type) is + select min(c.posnr) posnr, + count(1) anz + from comp c + where c.uebteilenr = ic_uebteilenr + and c.kompteilenr = ic_kompteilenr + and nvl(c.laenge, 0) = nvl(ic_laenge, 0); + xx_pos_im_ziel c_pos_im_ziel%rowtype; + + cursor c_comp_to_delete(ic_uebteilenr comp.uebteilenr%type) is + select posnr + from comp + where uebteilenr = ic_uebteilenr + and nvl(posnr, 0) < 0 + order by posnr; + + cursor c_comp_to_delete_2(ic_uebteilenr comp.uebteilenr%type) is + select posnr + from comp c + where uebteilenr = ic_uebteilenr + and not exists (select 1 + from k_sb_rd_comp r + where r.uebteilenr = c.uebteilenr + and r.kompteilenr = c.kompteilenr) + order by posnr; + + cursor c_ignorieren_jn(ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type, + ic_posnr comp.posnr%type) is + select nvl(k.ignorieren_jn, 'N') ignorieren_jn + from k_sb_rd_comp k + where k.uebteilenr = x_uebteilenr + and k.kompteilenr = ic_kompteilenr + and k.laenge = ic_laenge + and k.posnr = ic_posnr + and nvl(k.ignorieren_jn, 'N') = 'J'; + x_ignorieren_jn k_sb_rd_comp.ignorieren_jn%type; + + xx_comp comp%rowtype := null; + x_neuanlage boolean := false; + + x_anz_spalten number := 5; + x_spalte number := 1; + x_spalte_uebteilenr number := 1; + x_spalte_posnr number := 2; + x_spalte_kompteilenr number := 3; + x_spalte_menge number := 4; + x_spalte_laenge number := 5; + + x_menge comp.menge%type; + x_laenge comp.laenge%type; + -- x_laenge_tmp varchar2(100); + + x_archiv_erstellt boolean := false; + + cursor c_werte(ic_zeile varchar) is + select lvl, + replace(regexp_substr(ic_zeile, '[^;]*;?', 1, lvl), ';') wert, + count(*) over () anz + from dual cross apply (select level lvl + from dual + connect by level <= regexp_count(ic_zeile, ';') + 1); +begin + protok('k_ruledesigner.import_comp - start - i_voller_pfad: ' || i_voller_pfad, i_protok); + if i_voller_pfad is null then + o_meldung := 'k_ruledesigner.import_comp: Kein Dateipfad gegeben.'; + return false; + end if; + + if x_datei_name is null then + o_meldung := 'k_ruledesigner.import_comp: Konnte keinen Dateinamen aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + if x_verzeichnis is null then + o_meldung := 'k_ruledesigner.import_comp: Konnte kein Verzeichnis aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + -- Datei in work-Ordner verschieben + if edm.bs_verschieben(i_voller_pfad || ' ' || x_work_dir || x_datei_name) != '0' then + o_meldung := 'k_ruledesigner.import_comp: Fehler beim Verschieben der Datei ' || i_voller_pfad || ' in das WORK-Verzeichnis ' || x_verzeichnis || 'work/' || x_datei_name || '.'; + return false; + end if; + + if not tmp_tabelle_fuellen(x_datei_name, i_voller_pfad, o_meldung) then + delete from k_sb_rd_comp; + return false; + end if; + + -- Datei einlesen + x_file := sivas_utl_file.fopen(location => 'K_RD_TO_SIVAS_COMP_WORK', + filename => x_datei_name, + open_mode => 'R'); + + loop + + begin + sivas_utl_file.get_line(x_file, x_zeile); + exception + when no_data_found then + exit; + when others then + o_meldung := 'k_ruledesigner.import_comp: Fehler beim Verarbeiten der Datei ''' || x_work_dir || x_datei_name || '''.'; + return false; + end; + + -- if p_utf then + if true then + x_text := convert(x_zeile, 'WE8ISO8859P15', 'UTF8'); + else + x_text := x_zeile; + end if; + + if x_header_zeile then + x_header_zeile := false; + continue; + end if; + + xx_comp := null; + x_spalte := 1; + for xx_werte in c_werte(x_text) loop + if xx_werte.anz != x_anz_spalten then + sivas_utl_file.fclose(x_file); + o_meldung := 'Innerhalb der Datei ' || x_work_dir || x_datei_name || ' gibt es eine Zeile die nicht genau ' || x_anz_spalten || ' Spalten beinhaltet.'; + return false; + end if; + + if x_spalte = x_spalte_uebteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Keine Baugruppennummer gegeben.'; + return false; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + o_meldung := 'Ungueltige Baugruppennummer: ' || xx_werte.wert || '.'; + return false; + end if; + + open c_parts(trim(xx_werte.wert)); + fetch c_parts into xx_parts; + close c_parts; + + if xx_parts.teilenr is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Baugruppe ' || trim(xx_werte.wert) || ' existiert nicht im SIVAS-Teilestamm.'; + return false; + end if; + +/* if xx_parts.kzkauf != 'E' then + sivas_utl_file.fclose(x_file); + o_meldung := 'Das Teil ' || trim(xx_werte.wert) || ' ist keine Baugruppe.'; + return false; + end if;*/ + + xx_comp.uebteilenr := trim(xx_werte.wert); + + open c_beist_vorh(xx_comp.uebteilenr); + fetch c_beist_vorh into x_beist_vorh; + close c_beist_vorh; + if x_beist_vorh is not null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Baugruppe ''' || xx_comp.uebteilenr || ''' kann nicht importiert werden, da sie eine Kundenbeistellung enthält.'; + rd_protok(i_kontext => 'COMP', + i_pfad => i_voller_pfad, + i_fehler_jn => 'J', + i_meldung_beist => o_meldung); + return false; + end if; + + if x_erstes_mal then + open c_comp_exists(xx_comp.uebteilenr); + fetch c_comp_exists into x_comp_exists; + close c_comp_exists; + if x_comp_exists is null then + x_neuanlage := true; + end if; + end if; + + elsif x_spalte = x_spalte_posnr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Keine Positionsnummer gegeben.'; + return false; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + o_meldung := 'Ungueltige Positionsnummer: ' || xx_werte.wert || '.'; + return false; + end if; + xx_comp.posnr := to_number(xx_werte.wert)*10; + + elsif x_spalte = x_spalte_kompteilenr then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Keine Komponententeilenummer gegeben.'; + return false; + end if; + if length(xx_werte.wert) > 20 then + sivas_utl_file.fclose(x_file); + o_meldung := 'Ungueltige Komponententeilenummer: ' || xx_werte.wert || '.'; + return false; + end if; + xx_comp.kompteilenr := trim(xx_werte.wert); + + elsif x_spalte = x_spalte_menge then + if xx_werte.wert is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Keine Menge gegeben.'; + return false; + end if; + if not regexp_like(xx_werte.wert, '^[[:digit:]]+$') then + sivas_utl_file.fclose(x_file); + o_meldung := 'Ungueltige Menge: ' || xx_werte.wert || '.'; + return false; + end if; + + x_menge := to_number(trim(xx_werte.wert)); + elsif x_spalte = x_spalte_laenge and trim(xx_werte.wert) is not null /*and + regexp_like(regexp_replace(xx_werte.wert,'[[:space:]]',' '), '^[[:digit:]]+$')*/ then + + -- x_laenge_tmp_str := REGEXP_REPLACE (trim(xx_werte.wert), '\D'); + -- x_laenge_tmp_str := substr(x_laenge_tmp_str, 1, 3); + -- x_laenge := to_number(x_laenge_tmp_str); + -- x_laenge_tmp := trim(xx_werte.wert); + -- x_laenge_tmp := regexp_replace(trim(xx_werte.wert), '\D\,'); + -- x_laenge_tmp := replace(regexp_replace(trim(xx_werte.wert), '\D\,'), ',', '.'); + x_laenge := rd_to_number(xx_werte.wert); + end if; + + x_spalte := x_spalte + 1; + end loop; + + open c_parts(xx_comp.kompteilenr); + fetch c_parts into xx_parts; + close c_parts; + + if xx_parts.teilenr is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Komponente ' || xx_comp.kompteilenr || ' existiert nicht im SIVAS-Teilestamm.'; + return false; + end if; + + if xx_parts.abw_anzahl_jn = 'J' then + if x_laenge is null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Komponente ' || xx_comp.kompteilenr || ' ist ein Halbzeug, jedoch wurde keine Laenge uebergeben.'; + return false; + end if; + + xx_comp.abw_anzahl := x_menge; + xx_comp.laenge := x_laenge; + xx_comp.menge := x_menge * x_laenge / 1000; + else + xx_comp.abw_anzahl := null; + xx_comp.laenge := null; + xx_comp.menge := x_menge; + end if; + + if x_erstes_mal then + x_erstes_mal := false; + + -- delete from k_sb_rd_comp; + + x_archiv_erstellt := stkl_archiv_erstellen(i_uebteilenr => xx_comp.uebteilenr, + i_custom => true); + + delete from stkl_kopf where uebteilenr = xx_comp.uebteilenr; + insert into stkl_kopf (uebteilenr, manu) values (xx_comp.uebteilenr, 1); + + -- AJ/20240701: + -- Nicht mehr die Stückliste komplett löschen, sondern nach Teilenr + Länge differenzieren + -- delete from comp where uebteilenr = xx_comp.uebteilenr; + end if; + + -- insert into k_sb_rd_comp(uebteilenr, kompteilenr, laenge) values (xx_comp.uebteilenr, xx_comp.kompteilenr, xx_comp.laenge); + + x_ignorieren_jn := null; + open c_ignorieren_jn(xx_comp.kompteilenr, + xx_comp.laenge, + xx_comp.posnr / 10); + fetch c_ignorieren_jn into x_ignorieren_jn; + close c_ignorieren_jn; + if nvl(x_ignorieren_jn, 'N') = 'J' then + continue; + end if; + + xx_pos_im_ziel.posnr := null; + xx_pos_im_ziel.anz := null; + if not x_neuanlage then + open c_pos_im_ziel(xx_comp.uebteilenr, + xx_comp.kompteilenr, + xx_comp.laenge); + fetch c_pos_im_ziel into xx_pos_im_ziel; + close c_pos_im_ziel; + end if; + + if nvl(xx_pos_im_ziel.anz, 0) > 1 then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Baugruppe ''' || xx_comp.uebteilenr || ''' kann nicht importiert werden, da das Teil ''' || xx_comp.kompteilenr || ''' und die Länge ' || xx_comp.laenge || ' ' || xx_pos_im_ziel.anz || 'x im Ziel vorhanden sind.'; + return false; + end if; + + x_uebteilenr := xx_comp.uebteilenr; + + update stkl_regel r + set r.posnr = r.posnr * -1 + where r.uebteilenr = xx_comp.uebteilenr + and r.posnr = xx_comp.posnr; + + update var_teil_bedingung_2 v + set v.posnr = v.posnr * -1 + where v.uebteilenr = xx_comp.uebteilenr + and v.posnr = xx_comp.posnr; + + update comp c + set c.posnr = c.posnr * -1 + where c.uebteilenr = xx_comp.uebteilenr + and c.posnr = xx_comp.posnr; + + if x_neuanlage or xx_pos_im_ziel.posnr is null then + xx_comp.varianten := 0; + if not objekt_anlage.comp_anlegen(i_uebteilenr => xx_comp.uebteilenr, + io_posnr => xx_comp.posnr, + io_varianten => xx_comp.varianten, + i_kompteilenr => xx_comp.kompteilenr, + io_menge => xx_comp.menge, + i_abw_anzahl => xx_comp.abw_anzahl, + i_laenge => xx_comp.laenge, + o_meldung => x_meldung, + i_protok => 'N') then + sivas_utl_file.fclose(x_file); + o_meldung := 'Fehler beim Anlegen der Komponente ' || xx_comp.kompteilenr || ': ' || x_meldung; + return false; + end if; + else + begin + update stkl_regel r + set r.posnr = xx_comp.posnr + where r.uebteilenr = xx_comp.uebteilenr + and r.posnr = (select c.posnr + from comp c + where c.uebteilenr = xx_comp.uebteilenr + and c.kompteilenr = xx_comp.kompteilenr + and nvl(c.laenge, 0) = nvl(xx_comp.laenge, 0)); + + update var_teil_bedingung_2 v + set v.posnr = xx_comp.posnr + where v.uebteilenr = xx_comp.uebteilenr + and v.posnr = (select c.posnr + from comp c + where c.uebteilenr = xx_comp.uebteilenr + and c.kompteilenr = xx_comp.kompteilenr + and nvl(c.laenge, 0) = nvl(xx_comp.laenge, 0)); + + update comp c + set c.menge = xx_comp.menge, + c.abw_anzahl = xx_comp.abw_anzahl, + c.posnr = xx_comp.posnr + where c.uebteilenr = xx_comp.uebteilenr + and c.kompteilenr = xx_comp.kompteilenr + and nvl(c.laenge, 0) = nvl(xx_comp.laenge, 0); + exception + when others then + sivas_utl_file.fclose(x_file); + o_meldung := 'Fehler bei Verarbeitung der Komponente ' || xx_comp.kompteilenr || ': ' || sqlerrm; + return false; + end; + end if; + + end loop; + + -- Über alle negativen Posnrs iterieren und löschen + for xx_comp_to_delete in c_comp_to_delete(x_uebteilenr) loop + delete from stkl_regel r + where r.uebteilenr = x_uebteilenr + and r.posnr = xx_comp_to_delete.posnr; + + delete from var_teil_bedingung_2 v + where v.uebteilenr = x_uebteilenr + and v.posnr = xx_comp_to_delete.posnr; + + delete from comp c + where c.uebteilenr = x_uebteilenr + and c.posnr = xx_comp_to_delete.posnr; + end loop; + + -- Alle Positionen löschen, deren Komponente in der neuen CSV nicht vorkommen + for xx_comp_to_delete in c_comp_to_delete_2(x_uebteilenr) loop + delete from stkl_regel r + where r.uebteilenr = x_uebteilenr + and r.posnr = xx_comp_to_delete.posnr; + + delete from var_teil_bedingung_2 v + where v.uebteilenr = x_uebteilenr + and v.posnr = xx_comp_to_delete.posnr; + + delete from comp c + where c.uebteilenr = x_uebteilenr + and c.posnr = xx_comp_to_delete.posnr; + end loop; + + if not stkl_archiv_erstellen(x_uebteilenr, false, x_archiv_erstellt) then null; end if; + + if not x_erstes_mal then + update parts p + set p.stklcode = 'J' + where p.teilenr = x_uebteilenr; + end if; + + update comp c + set c.menge = nvl(c.abw_anzahl, 0) * ( ( nvl(c.laenge, 0) / 1000 ) + ( nvl(c.zuschnitt, 0) / 1000 ) ) + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0; + + sivas_utl_file.fclose(x_file); + + return true; +end; + +-------------------------------------------------------------------------------------------- + +procedure write_new_bom(i_uebteilenr in comp.uebteilenr%type, + o_archiv_erstellt out boolean) is + cursor c_was_zu_tun is + select 'J' was_zu_tun from tmp_codes_case_12_or_13 union + select 'J' was_zu_tun from tmp_codes_case_13 union + select 'J' was_zu_tun from tmp_ids_to_delete union + select 'J' was_zu_tun from tmp_posnrs_case_11 union + select 'J' was_zu_tun from tmp_posnrs_case_12 union + select 'J' was_zu_tun from tmp_posnrs_case_131 union + select 'J' was_zu_tun from tmp_posnrs_case_132 union + select 'J' was_zu_tun from tmp_update_data; + x_was_zu_tun varchar2(1); +begin + get_codes_case_12_or_13(i_uebteilenr); + get_codes_case_13(i_uebteilenr); + get_case_11_positions(i_uebteilenr); + get_case_12_positions(i_uebteilenr); + get_case_131_positions(i_uebteilenr); + get_case_132_positions(i_uebteilenr); + get_ids_to_delete(i_uebteilenr); + get_update_data(i_uebteilenr); + + open c_was_zu_tun; + fetch c_was_zu_tun into x_was_zu_tun; + close c_was_zu_tun; + + if nvl(x_was_zu_tun, 'N') = 'J' then + o_archiv_erstellt := stkl_archiv_erstellen(i_uebteilenr => i_uebteilenr, + i_custom => true); + else + o_archiv_erstellt := false; + end if; + + do_delete; + + update comp c + set c.posnr = c.posnr * -1 + where c.uebteilenr = i_uebteilenr; + + update stkl_regel r + set r.posnr = r.posnr * -1 + where r.uebteilenr = i_uebteilenr; + + do_insert(i_uebteilenr); + do_update(i_uebteilenr); + cleanup(i_uebteilenr); +end; + +-------------------------------------------------------------------------------------------- + +function import_comp(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean is + x_datei_name varchar2(500) := substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1); + x_verzeichnis varchar2(2000) := substr(i_voller_pfad, 1, instr(i_voller_pfad, '/', -1)); + x_work_dir varchar2(2000) := x_verzeichnis || 'work/'; + + x_file utl_file.file_type; + x_zeile varchar2(4000); + x_text varchar2(4000); + x_header_zeile boolean := true; + x_erstes_mal boolean := true; + x_meldung varchar2(4000); + + x_uebteilenr comp.uebteilenr%type; + + cursor c_parts(ic_teilenr comp.kompteilenr%type) is + select nvl(p.abw_anzahl_jn, 'N') abw_anzahl_jn, + p.teilenr, + nvl(p.kzkauf, 'K') kzkauf + from parts p + where p.teilenr = ic_teilenr; + xx_parts c_parts%rowtype; + + cursor c_comp_exists(ic_teilenr comp.uebteilenr%type) is + select c.kompteilenr + from comp c + where c.uebteilenr = ic_teilenr; + x_comp_exists comp.kompteilenr%type; + + cursor c_pos_im_ziel(ic_uebteilenr comp.uebteilenr%type, + ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type) is + select min(c.posnr) posnr, + count(1) anz + from comp c + where c.uebteilenr = ic_uebteilenr + and c.kompteilenr = ic_kompteilenr + and nvl(c.laenge, 0) = nvl(ic_laenge, 0); + xx_pos_im_ziel c_pos_im_ziel%rowtype; + + cursor c_comp_to_delete(ic_uebteilenr comp.uebteilenr%type) is + select posnr + from comp + where uebteilenr = ic_uebteilenr + and nvl(posnr, 0) < 0 + order by posnr; + + cursor c_comp_to_delete_2(ic_uebteilenr comp.uebteilenr%type) is + select posnr + from comp c + where uebteilenr = ic_uebteilenr + and not exists (select 1 + from k_sb_rd_comp r + where r.uebteilenr = c.uebteilenr + and r.kompteilenr = c.kompteilenr) + order by posnr; + + cursor c_ignorieren_jn(ic_kompteilenr comp.kompteilenr%type, + ic_laenge comp.laenge%type, + ic_posnr comp.posnr%type) is + select nvl(k.ignorieren_jn, 'N') ignorieren_jn + from k_sb_rd_comp k + where k.uebteilenr = x_uebteilenr + and k.kompteilenr = ic_kompteilenr + and k.laenge = ic_laenge + and k.posnr = ic_posnr + and nvl(k.ignorieren_jn, 'N') = 'J'; + x_ignorieren_jn k_sb_rd_comp.ignorieren_jn%type; + + cursor c_beist_vorh is + select c.kompteilenr + from comp c + where c.uebteilenr = x_uebteilenr + and nvl(c.kz_lieferanten_beistellung, 'N') = 'J'; + x_beist_vorh comp.kompteilenr%type; + + xx_comp comp%rowtype := null; + x_neuanlage boolean := false; + + x_anz_spalten number := 5; + x_spalte number := 1; + x_spalte_uebteilenr number := 1; + x_spalte_posnr number := 2; + x_spalte_kompteilenr number := 3; + x_spalte_menge number := 4; + x_spalte_laenge number := 5; + + x_menge comp.menge%type; + x_laenge comp.laenge%type; + + x_archiv_erstellt boolean := false; + + cursor c_werte(ic_zeile varchar) is + select lvl, + replace(regexp_substr(ic_zeile, '[^;]*;?', 1, lvl), ';') wert, + count(*) over () anz + from dual cross apply (select level lvl + from dual + connect by level <= regexp_count(ic_zeile, ';') + 1); +begin + protok('k_ruledesigner.import_comp_2 - start - i_voller_pfad: ' || i_voller_pfad, i_protok); + if i_voller_pfad is null then + o_meldung := 'k_ruledesigner.import_comp_2: Kein Dateipfad gegeben.'; + return false; + end if; + + if x_datei_name is null then + o_meldung := 'k_ruledesigner.import_comp_2: Konnte keinen Dateinamen aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + if x_verzeichnis is null then + o_meldung := 'k_ruledesigner.import_comp_2: Konnte kein Verzeichnis aus dem Dateipfad ''' || i_voller_pfad || ''' ermitteln.'; + return false; + end if; + + -- Datei in work-Ordner verschieben + if edm.bs_verschieben(i_voller_pfad || ' ' || x_work_dir || x_datei_name) != '0' then + o_meldung := 'k_ruledesigner.import_comp_2: Fehler beim Verschieben der Datei ' || i_voller_pfad || ' in das WORK-Verzeichnis ' || x_verzeichnis || 'work/' || x_datei_name || '.'; + return false; + end if; + + if not insert_csv_data(x_datei_name, x_uebteilenr, o_meldung) then + delete from k_sb_rd_comp; + return false; + end if; + + open c_beist_vorh; + fetch c_beist_vorh into x_beist_vorh; + close c_beist_vorh; + if x_beist_vorh is not null then + sivas_utl_file.fclose(x_file); + o_meldung := 'Die Baugruppe ''' || x_uebteilenr || ''' kann nicht importiert werden, da sie eine Kundenbeistellung enthält.'; + rd_protok(i_kontext => 'COMP', + i_pfad => i_voller_pfad, + i_fehler_jn => 'J', + i_meldung_beist => o_meldung); + return false; + end if; + + send_av_wfs(x_uebteilenr, i_voller_pfad); + send_tos_wfs(x_uebteilenr, i_voller_pfad); + + write_new_bom(x_uebteilenr, x_archiv_erstellt); + + if not stkl_archiv_erstellen(x_uebteilenr, false, x_archiv_erstellt) then null; end if; + + if not x_erstes_mal then + update parts p + set p.stklcode = 'J' + where p.teilenr = x_uebteilenr; + end if; + + update comp c + set c.menge = nvl(c.abw_anzahl, 0) * ( ( nvl(c.laenge, 0) / 1000 ) + ( nvl(c.zuschnitt, 0) / 1000 ) ) + where c.uebteilenr = x_uebteilenr + and nvl(c.laenge, 0) != 0; + + sivas_utl_file.fclose(x_file); + + return true; +end; + +-------------------------------------------------------------------------------------------- + +function import_parts_aend_dokumente(i_voller_pfad in filesystem_verzeichnis.pfad_datei%type, + o_meldung out varchar2, + i_protok in varchar default 'N') return boolean is + x_ext varchar2(3) := upper(substr(trim(i_voller_pfad), instr(i_voller_pfad, '.', -4)+1)); + x_teilenr parts.teilenr%type := substr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), 1, instr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), '-')-1); + x_aend_index parts_aend.aend_index%type := upper(substr(substr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), instr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), '-')+1), 1, instr(substr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), instr(substr(i_voller_pfad, instr(i_voller_pfad, '/', -1)+1), '-')+1), '.')-1)); + + cursor c_parts_aend_freig is + select upper(max(pa.aend_index)) aend_index + from parts_aend pa + where pa.teilenr = x_teilenr + and pa.freigabe_datum = nvl((select max(paa.freigabe_datum) + from parts_aend paa + where paa.teilenr = x_teilenr), pa.freigabe_datum); + xx_parts_aend_freig c_parts_aend_freig%rowtype; + + cursor c_parts_aend_exists is + select aend_index + from parts_aend + where teilenr = x_teilenr + and aend_index = upper(x_aend_index); + x_parts_aend_exists parts_aend.aend_index%type; + + x_lfdnr parts_aend_dokumente.lfdnr%type; + x_windows_pfad parts.zeichnung_anzeige%type; + +begin + if x_ext is null then + o_meldung := 'Die Dateiendung fuer ''' || i_voller_pfad || ''' konnte nicht ermittelt werden.'; + return false; + end if; + + open c_parts_aend_exists; + fetch c_parts_aend_exists into x_parts_aend_exists; + close c_parts_aend_exists; + if x_parts_aend_exists is null then + o_meldung := 'Der Index ''' || x_aend_index || ''' fuer das Teil ''' || x_teilenr || ''' ist in SIVAS nicht erfasst.'; + return false; + end if; + + if lower(sys_context('userenv','instance_name')) like '%schul%' then + x_windows_pfad := replace(replace(trim(i_voller_pfad), '/u/sivas/ruledesigner/Schulung/Archiv', '\\ssg.local\freigaben\SIVAS_CAD_EDM\Schulung\Archiv'), '/', '\'); + else + x_windows_pfad := replace(replace(trim(i_voller_pfad), '/u/sivas/ruledesigner/Archiv', '\\ssg.local\freigaben\SIVAS_CAD_EDM\Archiv'), '/', '\'); + end if; + + if x_ext = 'PDF' then + open c_parts_aend_freig; + fetch c_parts_aend_freig into xx_parts_aend_freig; + close c_parts_aend_freig; + + if nvl(xx_parts_aend_freig.aend_index, 'XYZ') = upper(x_aend_index) then + update parts + set zeichnung_anzeige = x_windows_pfad + where teilenr = x_teilenr; + + update parts_aend pa + set pa.zeichnung_anzeige = x_windows_pfad + where pa.teilenr = x_teilenr + and upper(pa.aend_index) = upper(x_aend_index); + end if; + end if; + + delete from parts_aend_dokumente pad + where pad.teilenr = x_teilenr + and upper(pad.aend_index) = upper(x_aend_index) + and upper(trim(pad.dok_pfad)) = upper(x_windows_pfad); + + x_lfdnr := allgemein.get_next_sequence_no('PARTS_AEND_DOK_SEQ'); + insert into parts_aend_dokumente(manu, + teilenr, + aend_index, + unter_ind, + anl_datum, + aender_datum, + dok_type, + dok_pfad, + lfdnr) + values(1, + x_teilenr, + upper(x_aend_index), + 0, + sysdate, + sysdate, + x_ext, + x_windows_pfad, + x_lfdnr); + + return true; +end; + +-------------------------------------------------------------------------- + +function rd_to_number(i_numeric_string in varchar2) return number is + x_numeric_string varchar2(500):= trim(i_numeric_string); + x_zaehler number := 1; + x_str_tmp varchar2(1); + x_str varchar2(50); +begin + x_str_tmp := substr(x_numeric_string, x_zaehler, 1); + while x_str_tmp is not null loop + + if regexp_like(x_str_tmp, '^[[:digit:]]+$') then + x_str := x_str || x_str_tmp; + elsif x_str_tmp = ',' or x_str_tmp = '.' then + x_str := x_str || ','; + else + exit; + end if; + + x_zaehler := x_zaehler + 1; + x_str_tmp := substr(x_numeric_string, x_zaehler, 1); + end loop; + + return to_number(x_str); +end; + +-------------------------------------------------------------------------- +function rd_user_to_sivas(i_rd_user in varchar2) return varchar2 is + x_sivas_user varchar2(20) := trim(upper(i_rd_user)); +begin + if x_sivas_user = 'B.MUELLER' then + x_sivas_user := 'B.MÜLLER'; + end if; + + return x_sivas_user; +end; + +-------------------------------------------------------------------------- + +procedure index_klein_zu_gross is + + cursor c_parts_aend is + select pa.* + from parts_aend pa + where upper(pa.aend_index) <> pa.aend_index + and freigabe_datum is not null + and nvl(kz_gesperrt, 'N') = 'N' + and not exists (select 1 + from parts_aend paa + where paa.teilenr = pa.teilenr + and paa.aend_index = upper(pa.aend_index)); + xx_parts_aend parts_aend%rowtype; + + cursor c_parts_aend_text(ic_teilenr parts_aend.teilenr%type, + ic_aend_index parts_aend.aend_index%type) is + select * + from parts_aend_text pat + where pat.teilenr = ic_teilenr + and pat.aend_index = ic_aend_index; + + cursor c_parts_aend_dokumente(ic_teilenr parts_aend.teilenr%type, + ic_aend_index parts_aend.aend_index%type) is + select * + from parts_aend_dokumente pad + where pad.teilenr = ic_teilenr + and pad.aend_index = ic_aend_index; +begin + open c_parts_aend; + fetch c_parts_aend into xx_parts_aend; + close c_parts_aend; + + while xx_parts_aend.aend_index is not null loop + + xx_parts_aend.freigabe_datum := xx_parts_aend.freigabe_datum + 1; + xx_parts_aend.aend_index := upper(xx_parts_aend.aend_index); + insert into parts_aend values xx_parts_aend; + + for xx_parts_aend_text in c_parts_aend_text(xx_parts_aend.teilenr, xx_parts_aend.aend_index) loop + xx_parts_aend_text.aend_index := upper(xx_parts_aend.aend_index); + insert into parts_aend_text values xx_parts_aend_text; + end loop; + + for xx_parts_aend_dokumente in c_parts_aend_dokumente(xx_parts_aend.teilenr, xx_parts_aend.aend_index) loop + xx_parts_aend_dokumente.aend_index := upper(xx_parts_aend.aend_index); + insert into parts_aend_dokumente values xx_parts_aend_dokumente; + end loop; + + xx_parts_aend.aend_index := null; + open c_parts_aend; + fetch c_parts_aend into xx_parts_aend; + close c_parts_aend; + + end loop; +end; + +---------------------------------------------------------------------------------- + +procedure sik_schreiben(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) is + x_schluessel klas_auspraegung.schluessel%type; + + cursor c_regel_vorh is + select uebteilenr + from stkl_regel r + where r.uebteilenr = i_uebteilenr + and r.posnr = i_posnr + and r.varianten = i_varianten; + x_regel_vorh stkl_regel.uebteilenr%type; + + cursor c_bed_vorh is + select b.uebteilenr + from var_teil_bedingung_2 b + where b.uebteilenr = i_uebteilenr + and b.posnr = i_posnr + and b.varianten = i_varianten; + x_bed_vorh var_teil_bedingung_2.uebteilenr%type; + + cursor c_comp is + select c.dispo_aktiv_jn, + c.zuschnitt, + c.ruestcode + from comp c + where c.uebteilenr = i_uebteilenr + and c.posnr = i_posnr + and c.varianten = i_varianten; + xx_comp c_comp%rowtype; + + x_lfdnr_rb_vorh klas_auspraegung.lfd_nr%type; + x_lfdnr_dispo klas_auspraegung.lfd_nr%type; + + x_rb_vorh klas_auspraegung.text%type; + x_dispoaktiv klas_auspraegung.text%type; + x_ruestcode klas_auspraegung.text%type; + x_zuschnitt klas_auspraegung.wert%type; + +begin + if not schluessel.erstellen(i_tabelle => 'COMP_HIST', + i_feld_1 => i_lfdnr_hist, + i_feld_2 => i_uebteilenr, + i_feld_3 => i_posnr, + i_feld_4 => i_varianten, + i_feld_5 => i_manu, + o_schluessel => x_schluessel, + i_protok => 'N') then + return; + end if; + + if x_schluessel is null then + return; + end if; + + open c_bed_vorh; + fetch c_bed_vorh into x_bed_vorh; + close c_bed_vorh; + if x_bed_vorh is null then + open c_regel_vorh; + fetch c_regel_vorh into x_regel_vorh; + close c_regel_vorh; + end if; + + if x_bed_vorh is not null or x_regel_vorh is not null then + x_rb_vorh := 'Ja'; + x_lfdnr_rb_vorh := g_lfdnr_rb_vorh_ja; + else + x_rb_vorh := 'Nein'; + x_lfdnr_rb_vorh := g_lfdnr_rb_vorh_nein; + end if; + + open c_comp; + fetch c_comp into xx_comp; + close c_comp; + + if nvl(xx_comp.dispo_aktiv_jn, 'N') = 'J' then + x_dispoaktiv := 'Ja'; + x_lfdnr_dispo := g_lfdnr_dispo_ja; + else + x_dispoaktiv := 'Nein'; + x_lfdnr_dispo := g_lfdnr_dispo_nein; + end if; + + x_zuschnitt := xx_comp.zuschnitt; + x_ruestcode := xx_comp.ruestcode; + + delete from klas_auspraegung k + where k.kenner = 'COMP_HIST1' + and leiste = 'CompHist1' + and schluessel = x_schluessel; + + insert into klas_auspraegung(kenner, + schluessel, + klasse, + leiste, + lfd_nr, + text, + erfasser, + erf_datum) + values ('COMP_HIST1', + x_schluessel, + -1, + 'CompHist1', + x_lfdnr_rb_vorh, + x_rb_vorh, + user, + sysdate); + + insert into klas_auspraegung(kenner, + schluessel, + klasse, + leiste, + lfd_nr, + text, + erfasser, + erf_datum) + values ('COMP_HIST1', + x_schluessel, + -1, + 'CompHist1', + x_lfdnr_dispo, + x_dispoaktiv, + user, + sysdate); + + insert into klas_auspraegung(kenner, + schluessel, + klasse, + leiste, + lfd_nr, + wert, + erfasser, + erf_datum) + values ('COMP_HIST1', + x_schluessel, + -1, + 'CompHist1', + g_lfdnr_zuschnitt, + x_zuschnitt, + user, + sysdate); + + insert into klas_auspraegung(kenner, + schluessel, + klasse, + leiste, + lfd_nr, + text, + erfasser, + erf_datum) + values ('COMP_HIST1', + x_schluessel, + -1, + 'CompHist1', + g_lfdnr_ruestcode, + x_ruestcode, + user, + sysdate); +end; + +---------------------------------------------------------------------------------- + +procedure sik_loeschen(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) is + x_schluessel klas_auspraegung.schluessel%type; +begin + if not schluessel.erstellen(i_tabelle => 'COMP_HIST', + i_feld_1 => i_lfdnr_hist, + i_feld_2 => i_uebteilenr, + i_feld_3 => i_posnr, + i_feld_4 => i_varianten, + i_feld_5 => i_manu, + o_schluessel => x_schluessel, + i_protok => 'N') then + return; + end if; + + if x_schluessel is null then + return; + end if; + + delete from klas_auspraegung k + where k.kenner = 'COMP_HIST1' + and leiste = 'CompHist1' + and schluessel = x_schluessel; +end; + +---------------------------------------------------------------------------------- + +procedure sik_wert(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type, + i_lfd_nr in klas_auspraegung.lfd_nr%type, + o_text out klas_auspraegung.text%type, + o_wert out klas_auspraegung.wert%type) is + cursor c_sik(ic_schluessel klas_auspraegung.schluessel%type) is + select k.text, + k.wert + from klas_auspraegung k + where k.kenner = 'COMP_HIST1' + and k.leiste = 'CompHist1' + and k.klasse = -1 + and k.lfd_nr = i_lfd_nr + and k.schluessel = ic_schluessel; + xx_sik c_sik%rowtype; + + x_feld1 varchar2(4000) := to_char(i_lfdnr_hist); + x_feld2 varchar2(4000) := i_uebteilenr; + x_feld3 varchar2(4000) := to_char(i_posnr); + x_feld4 varchar2(4000) := to_char(i_varianten); + x_feld5 varchar2(4000) := to_char(i_manu); + x_feld6 varchar2(4000) := null; + x_feld7 varchar2(4000) := null; + x_feld8 varchar2(4000) := null; + x_feld9 varchar2(4000) := null; + x_schluessel klas_auspraegung.schluessel%type; +begin + if not schluessel.erstellen(i_tabelle => 'COMP_HIST', + i_feld_1 => x_feld1, + i_feld_2 => x_feld2, + i_feld_3 => x_feld3, + i_feld_4 => x_feld4, + i_feld_5 => x_feld5, + i_feld_6 => x_feld6, + i_feld_7 => x_feld7, + i_feld_8 => x_feld8, + i_feld_9 => x_feld9, + o_schluessel => x_schluessel) or x_schluessel is null then + o_text := null; + o_wert := null; + return; + end if; + + open c_sik(x_schluessel); + fetch c_sik into xx_sik; + close c_sik; + + o_text := xx_sik.text; + o_wert := xx_sik.wert; +end; + +---------------------------------------------------------------------------------- + +function comp_hist_rb_vorh_jn(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2 is + + x_text klas_auspraegung.text%type; + x_wert klas_auspraegung.wert%type; +begin + sik_wert(i_lfdnr_hist => i_lfdnr_hist, + i_uebteilenr => i_uebteilenr, + i_posnr => i_posnr, + i_varianten => i_varianten, + i_manu => i_manu, + i_lfd_nr => g_lfdnr_rb_vorh_ja, + o_text => x_text, + o_wert => x_wert); + + if nvl(x_text, 'x') = 'Ja' then + return 'J'; + end if; + + return 'N'; +end; + +---------------------------------------------------------------------------------- + +function comp_hist_dispo_jn(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2 is + + x_text klas_auspraegung.text%type; + x_wert klas_auspraegung.wert%type; +begin + sik_wert(i_lfdnr_hist => i_lfdnr_hist, + i_uebteilenr => i_uebteilenr, + i_posnr => i_posnr, + i_varianten => i_varianten, + i_manu => i_manu, + i_lfd_nr => g_lfdnr_dispo_ja, + o_text => x_text, + o_wert => x_wert); + + if nvl(x_text, 'x') = 'Ja' then + return 'J'; + end if; + + return 'N'; +end; + +---------------------------------------------------------------------------------- + +function comp_hist_zuschnitt(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return number is + + x_text klas_auspraegung.text%type; + x_wert klas_auspraegung.wert%type; +begin + sik_wert(i_lfdnr_hist => i_lfdnr_hist, + i_uebteilenr => i_uebteilenr, + i_posnr => i_posnr, + i_varianten => i_varianten, + i_manu => i_manu, + i_lfd_nr => g_lfdnr_zuschnitt, + o_text => x_text, + o_wert => x_wert); + + return x_wert; +end; + +---------------------------------------------------------------------------------- + +function comp_hist_ruestcode(i_lfdnr_hist in comp_hist.lfdnr_hist%type, + i_uebteilenr in comp_hist.uebteilenr%type, + i_posnr in comp_hist.posnr%type, + i_varianten in comp_hist.varianten%type, + i_manu in comp_hist.manu%type) return varchar2 is + + x_text klas_auspraegung.text%type; + x_wert klas_auspraegung.wert%type; +begin + sik_wert(i_lfdnr_hist => i_lfdnr_hist, + i_uebteilenr => i_uebteilenr, + i_posnr => i_posnr, + i_varianten => i_varianten, + i_manu => i_manu, + i_lfd_nr => g_lfdnr_ruestcode, + o_text => x_text, + o_wert => x_wert); + + if x_text is null then + return null; + end if; + + return x_text || ' - ' || bez.bez_ruestcode(x_text); +end; + +end; +/