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; /