From a932fd0e8ed028ddb53796fedd03fefa65d17a62 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Mon, 8 Jul 2024 14:46:02 +0200 Subject: [PATCH] =?UTF-8?q?Kostentr=C3=A4gerdatei=20Reader=20Grundstruktur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dakota/Dakota.csproj | 9 +++ Dakota/Logic/DakotaKTDReader.cs | 71 +++++++++++++++++++ Dakota/Models/Auftragsdatei/Auftragsdatei.cs | 2 +- .../Models/Auftragsdatei/AuftragssatzPart1.cs | 2 +- .../Models/Auftragsdatei/AuftragssatzPart2.cs | 2 +- .../Models/Auftragsdatei/AuftragssatzPart3.cs | 2 +- .../Models/Auftragsdatei/AuftragssatzPart4.cs | 2 +- Dakota/Models/IRowable.cs | 2 +- Dakota/Models/Nachrichten/Nachricht.cs | 2 +- Dakota/Models/Nachrichten/NachrichtKTD.cs | 71 +++++++++++++++++++ Dakota/Models/Schlüssels/Schlüssel.cs | 11 +++ .../Schlüssels/SchlüsselArtDerVerknüpfung.cs | 32 +++++++++ .../SchlüsselKTDVerarbeitungskennzeichen.cs | 35 +++++++++ Dakota/Models/Segmente/KTD/SegmentKTD.cs | 15 ++++ Dakota/Models/Segmente/KTD/SegmentKTDFKT.cs | 21 ++++++ Dakota/Models/Segmente/KTD/SegmentKTDIDK.cs | 32 +++++++++ Dakota/Models/Segmente/KTD/SegmentKTDVDT.cs | 16 +++++ Dakota/Models/Segmente/KTD/SegmentKTDVKG.cs | 52 ++++++++++++++ Host/Host.csproj.user | 2 +- 19 files changed, 373 insertions(+), 8 deletions(-) create mode 100644 Dakota/Logic/DakotaKTDReader.cs create mode 100644 Dakota/Models/Nachrichten/NachrichtKTD.cs create mode 100644 Dakota/Models/Schlüssels/SchlüsselArtDerVerknüpfung.cs create mode 100644 Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs create mode 100644 Dakota/Models/Segmente/KTD/SegmentKTD.cs create mode 100644 Dakota/Models/Segmente/KTD/SegmentKTDFKT.cs create mode 100644 Dakota/Models/Segmente/KTD/SegmentKTDIDK.cs create mode 100644 Dakota/Models/Segmente/KTD/SegmentKTDVDT.cs create mode 100644 Dakota/Models/Segmente/KTD/SegmentKTDVKG.cs diff --git a/Dakota/Dakota.csproj b/Dakota/Dakota.csproj index 652c87eb9..7f4699e5a 100644 --- a/Dakota/Dakota.csproj +++ b/Dakota/Dakota.csproj @@ -42,6 +42,7 @@ + @@ -82,12 +83,15 @@ + + + @@ -104,6 +108,11 @@ + + + + + diff --git a/Dakota/Logic/DakotaKTDReader.cs b/Dakota/Logic/DakotaKTDReader.cs new file mode 100644 index 000000000..ab8d92f30 --- /dev/null +++ b/Dakota/Logic/DakotaKTDReader.cs @@ -0,0 +1,71 @@ +using Dakota.Models.Nachrichten; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Logic +{ + public class DakotaKTDReader + { + private static readonly string[] accept = new string[] { "UNH", "IDK", "VDT", "VKG", "UNT"}; + + internal Dictionary IK2NachrichtKTD { get; set; } + + public DakotaKTDReader(string ktd_folder_path) + { + var dir = new DirectoryInfo(ktd_folder_path); + + var files = dir.GetFiles(); + + foreach (var file in files) + { + var file_lines = File.ReadAllLines(file.FullName); + + foo(file.Name, file_lines); + } + } + + public void foo(string filename, string[] lines) + { + var length = lines.Length; + + Queue queue = new Queue(); + int first_line = 0; + for (int i = 0; i < length; i++) + { + var line = lines[i]; + + var type = GetType(line); + + if (type is null) + continue; + + if (type == "UNH") + { + first_line = i; + } + else if (type == "UNT") + { + if (NachrichtKTD.TryParse(queue.ToArray(), filename, first_line, out var nachricht)) + { + IK2NachrichtKTD.Add(nachricht.IKNummer, nachricht); + } + } + else + { + queue.Enqueue(line); + } + } + } + + private string GetType(string line) + { + var type = line.Substring(0, 3); + + return accept.Contains(type) ? type : null; + } + } +} diff --git a/Dakota/Models/Auftragsdatei/Auftragsdatei.cs b/Dakota/Models/Auftragsdatei/Auftragsdatei.cs index 8e9258c6e..7a2854a2b 100644 --- a/Dakota/Models/Auftragsdatei/Auftragsdatei.cs +++ b/Dakota/Models/Auftragsdatei/Auftragsdatei.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Auftragsdatei { - internal class Auftragsdatei : IRow + internal class Auftragsdatei : IRowable { public DakotaFile Parent { get; set; } diff --git a/Dakota/Models/Auftragsdatei/AuftragssatzPart1.cs b/Dakota/Models/Auftragsdatei/AuftragssatzPart1.cs index 4d549295f..e3538d5c6 100644 --- a/Dakota/Models/Auftragsdatei/AuftragssatzPart1.cs +++ b/Dakota/Models/Auftragsdatei/AuftragssatzPart1.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Auftragsdatei { - internal class AuftragssatzPart1 : IRow + internal class AuftragssatzPart1 : IRowable { public Auftragsdatei ParentAuftragsdatei { get; set; } diff --git a/Dakota/Models/Auftragsdatei/AuftragssatzPart2.cs b/Dakota/Models/Auftragsdatei/AuftragssatzPart2.cs index d1021cfa9..2d53fd47c 100644 --- a/Dakota/Models/Auftragsdatei/AuftragssatzPart2.cs +++ b/Dakota/Models/Auftragsdatei/AuftragssatzPart2.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Auftragsdatei { - public class AuftragssatzPart2 : IRow + public class AuftragssatzPart2 : IRowable { public DatenelementAuftragsdatei Satzformat { get; private set; } public DatenelementAuftragsdatei Satzlange { get; private set; } diff --git a/Dakota/Models/Auftragsdatei/AuftragssatzPart3.cs b/Dakota/Models/Auftragsdatei/AuftragssatzPart3.cs index 2f083c613..742f9dc87 100644 --- a/Dakota/Models/Auftragsdatei/AuftragssatzPart3.cs +++ b/Dakota/Models/Auftragsdatei/AuftragssatzPart3.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Auftragsdatei { - public class AuftragssatzPart3 : IRow + public class AuftragssatzPart3 : IRowable { public DatenelementAuftragsdatei Status { get; private set; } public DatenelementAuftragsdatei Wiederholung { get; private set; } diff --git a/Dakota/Models/Auftragsdatei/AuftragssatzPart4.cs b/Dakota/Models/Auftragsdatei/AuftragssatzPart4.cs index 03f0fed6d..d713348a3 100644 --- a/Dakota/Models/Auftragsdatei/AuftragssatzPart4.cs +++ b/Dakota/Models/Auftragsdatei/AuftragssatzPart4.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Auftragsdatei { - public class AuftragssatzPart4 : IRow + public class AuftragssatzPart4 : IRowable { public DatenelementAuftragsdatei EMailAdresseAbsender { get; private set; } public DatenelementAuftragsdatei DateiBezeichnung { get; private set; } diff --git a/Dakota/Models/IRowable.cs b/Dakota/Models/IRowable.cs index a3d9b3b07..fe955de91 100644 --- a/Dakota/Models/IRowable.cs +++ b/Dakota/Models/IRowable.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Dakota.Models { - internal interface IRow + internal interface IRowable { string GetRows(); } diff --git a/Dakota/Models/Nachrichten/Nachricht.cs b/Dakota/Models/Nachrichten/Nachricht.cs index 1abe5e17f..92eac1042 100644 --- a/Dakota/Models/Nachrichten/Nachricht.cs +++ b/Dakota/Models/Nachrichten/Nachricht.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Dakota.Models.Nachrichten { - internal abstract class Nachricht : IRow + internal abstract class Nachricht : IRowable { public abstract List GetAllSegments(); diff --git a/Dakota/Models/Nachrichten/NachrichtKTD.cs b/Dakota/Models/Nachrichten/NachrichtKTD.cs new file mode 100644 index 000000000..302a38995 --- /dev/null +++ b/Dakota/Models/Nachrichten/NachrichtKTD.cs @@ -0,0 +1,71 @@ +using Dakota.Models.Segmente; +using Dakota.Models.Segmente.KTD; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Nachrichten +{ + internal class NachrichtKTD : Nachricht + { + public string FileName { get; set; } + public int FirstLine { get; set; } + + public SegmentKTDIDK SegmentIDK { get; set; } + public SegmentKTDFKT SegmentFKT { get; set; } + public List SegmentVKG { get; set; } + + public NachrichtKTD() + { + SegmentVKG = new List(); + } + + public string IKNummer + { + get { return SegmentIDK.Institutionskennzeichen; } + } + + + public override List GetAllSegments() + { + throw new NotImplementedException(); + } + + public static bool TryParse(string[] rows, string filename, int firstline, out NachrichtKTD nachricht) + { + try + { + nachricht = Parse(rows, filename, firstline); + + return true; + } + catch(Exception e) + { + nachricht = null; + + return false; + } + } + public static NachrichtKTD Parse(string[] rows, string filename, int firstline) + { + var nachricht = new NachrichtKTD(); + + nachricht.SegmentIDK = SegmentKTDIDK.Parse(rows[0]); + nachricht.SegmentFKT = SegmentKTDFKT.Parse(rows[1]); + + var length = rows.Length; + + for (int i = 2; i < length; i++) + { + nachricht.SegmentVKG.Add(SegmentKTDVKG.Parse(rows[2])); + } + + nachricht.FileName = filename; + nachricht.FirstLine = firstline; + + return nachricht; + } + } +} diff --git a/Dakota/Models/Schlüssels/Schlüssel.cs b/Dakota/Models/Schlüssels/Schlüssel.cs index f9ea1e01a..b0e4eaba9 100644 --- a/Dakota/Models/Schlüssels/Schlüssel.cs +++ b/Dakota/Models/Schlüssels/Schlüssel.cs @@ -14,5 +14,16 @@ namespace Dakota.Models.Schlüssels { Value = val; } + + public static T GetSchlüsselSafe(IEnumerable list, string schlüssel) where T : Schlüssel + { + foreach (var t_schlüssel in list) + { + if (t_schlüssel.Value == schlüssel) + return t_schlüssel; + } + + return null; + } } } diff --git a/Dakota/Models/Schlüssels/SchlüsselArtDerVerknüpfung.cs b/Dakota/Models/Schlüssels/SchlüsselArtDerVerknüpfung.cs new file mode 100644 index 000000000..37a78f101 --- /dev/null +++ b/Dakota/Models/Schlüssels/SchlüsselArtDerVerknüpfung.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Schlüssels +{ + public class SchlüsselArtDerVerknüpfung : Schlüssel + { + public SchlüsselArtDerVerknüpfung(string val) : base(val) { } + + public static SchlüsselArtDerVerknüpfung VerweisVomIKderKvKarteZumKostentrager => new SchlüsselArtDerVerknüpfung("01"); + public static SchlüsselArtDerVerknüpfung VerweisAufDatenannahmestelleOhneEntschlusselungsbefugnis => new SchlüsselArtDerVerknüpfung("02"); + public static SchlüsselArtDerVerknüpfung VerweisAufDatenannahmestelleMitEntschlusselungsbefugnis => new SchlüsselArtDerVerknüpfung("03"); + + public static SchlüsselArtDerVerknüpfung Parse(string str) + { + var list = new SchlüsselArtDerVerknüpfung[] { + VerweisVomIKderKvKarteZumKostentrager , + VerweisAufDatenannahmestelleOhneEntschlusselungsbefugnis , + VerweisAufDatenannahmestelleMitEntschlusselungsbefugnis }; + + var schlüssel = GetSchlüsselSafe(list, str); + + if (schlüssel is null) + throw new DakotaException($"ArtDerVerknüpfung {str} nicht gefunden."); + + return schlüssel; + } + } +} diff --git a/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs b/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs new file mode 100644 index 000000000..ad2d47750 --- /dev/null +++ b/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs @@ -0,0 +1,35 @@ +using BS.Shared.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Schlüssels +{ + public class SchlüsselKTDVerarbeitungskennzeichen : Schlüssel + { + public SchlüsselKTDVerarbeitungskennzeichen(string val) : base(val) { } + + public static SchlüsselKTDVerarbeitungskennzeichen Neuanmeldung => new SchlüsselKTDVerarbeitungskennzeichen("01"); + public static SchlüsselKTDVerarbeitungskennzeichen Änderung => new SchlüsselKTDVerarbeitungskennzeichen("02"); + public static SchlüsselKTDVerarbeitungskennzeichen Stornierung => new SchlüsselKTDVerarbeitungskennzeichen("03"); + public static SchlüsselKTDVerarbeitungskennzeichen Unverändert => new SchlüsselKTDVerarbeitungskennzeichen("04"); + + public static SchlüsselKTDVerarbeitungskennzeichen Parse(string str) + { + var list = new SchlüsselKTDVerarbeitungskennzeichen[] { + Neuanmeldung , + Änderung , + Stornierung, + Unverändert}; + + var schlüssel = GetSchlüsselSafe(list, str); + + if (schlüssel is null) + throw new DakotaException($"KTDVerarbeitungskennzeichen {str} nicht gefunden."); + + return schlüssel; + } + } +} diff --git a/Dakota/Models/Segmente/KTD/SegmentKTD.cs b/Dakota/Models/Segmente/KTD/SegmentKTD.cs new file mode 100644 index 000000000..3c2ea127f --- /dev/null +++ b/Dakota/Models/Segmente/KTD/SegmentKTD.cs @@ -0,0 +1,15 @@ +using Dakota.Models.Daten; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Segmente.KTD +{ + internal abstract class SegmentKTD + { + public static char Trennzeichen => DakotaConfig.Trennzeichen[0]; + public static char Segmentendezeichen => DakotaConfig.Segmentendezeichen[0]; + } +} diff --git a/Dakota/Models/Segmente/KTD/SegmentKTDFKT.cs b/Dakota/Models/Segmente/KTD/SegmentKTDFKT.cs new file mode 100644 index 000000000..51ab3fb89 --- /dev/null +++ b/Dakota/Models/Segmente/KTD/SegmentKTDFKT.cs @@ -0,0 +1,21 @@ +using Dakota.Models.Schlüssels; +using System; + +namespace Dakota.Models.Segmente.KTD +{ + internal class SegmentKTDFKT : SegmentKTD + { + public SchlüsselKTDVerarbeitungskennzeichen Verarbeitungskennzeichen { get; set; } + + public static SegmentKTDFKT Parse(string row) + { + var segment = new SegmentKTDFKT(); + + var split = row.Trim(Segmentendezeichen).Split(Trennzeichen); + + segment.Verarbeitungskennzeichen = SchlüsselKTDVerarbeitungskennzeichen.Parse(split[1]); + + return segment; + } + } +} diff --git a/Dakota/Models/Segmente/KTD/SegmentKTDIDK.cs b/Dakota/Models/Segmente/KTD/SegmentKTDIDK.cs new file mode 100644 index 000000000..4287e9369 --- /dev/null +++ b/Dakota/Models/Segmente/KTD/SegmentKTDIDK.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Segmente.KTD +{ + internal class SegmentKTDIDK : SegmentKTD + { + public string Institutionskennzeichen { get; set; } + public string ArtDerInstitution { get; set; } + public string Kurzbezeichnung { get; set; } + public string VKNR { get; set; } + + public static SegmentKTDIDK Parse(string row) + { + var segment = new SegmentKTDIDK(); + + var split = row.Trim(Segmentendezeichen).Split(Trennzeichen); + + segment.Institutionskennzeichen = split[1]; + segment.ArtDerInstitution = split[2]; + segment.Kurzbezeichnung = split[3]; + + if(split.Length > 4) + segment.VKNR = split[4]; + + return segment; + } + } +} diff --git a/Dakota/Models/Segmente/KTD/SegmentKTDVDT.cs b/Dakota/Models/Segmente/KTD/SegmentKTDVDT.cs new file mode 100644 index 000000000..c898af4c4 --- /dev/null +++ b/Dakota/Models/Segmente/KTD/SegmentKTDVDT.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Segmente.KTD +{ + internal class SegmentKTDVDT : SegmentKTD + { + public static SegmentKTDVDT Parse(string row) + { + throw new NotImplementedException(); + } + } +} diff --git a/Dakota/Models/Segmente/KTD/SegmentKTDVKG.cs b/Dakota/Models/Segmente/KTD/SegmentKTDVKG.cs new file mode 100644 index 000000000..ff91399a3 --- /dev/null +++ b/Dakota/Models/Segmente/KTD/SegmentKTDVKG.cs @@ -0,0 +1,52 @@ +using Dakota.Models.Schlüssels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dakota.Models.Segmente.KTD +{ + internal class SegmentKTDVKG : SegmentKTD + { + public SchlüsselArtDerVerknüpfung ArtDerVerknüpfung { get; set; } + public string IKVerknüpfungspartners { get; set; } + public string Leistungserbringergruppe { get; set; } + public string IKAbrechnungsstelle { get; set; } + public string ArtDerDatenlieferung { get; set; } + public string ArtDesÜbermittlungsmediums { get; set; } + public string StandortDesLeistungserbringersNachBundesland { get; set; } + public string StandortDesLeistungserbringersNachKVBezirk { get; set; } + public string Abrechnungscode { get; set; } + public string Tarifkennzeichen { get; set; } + + public static SegmentKTDVKG Parse(string row) + { + var segment = new SegmentKTDVKG(); + + var split = row.Trim(Segmentendezeichen).Split(Trennzeichen); + + segment.ArtDerVerknüpfung = SchlüsselArtDerVerknüpfung.Parse(split[1]); + segment.IKVerknüpfungspartners = split[2]; + + if (split.Length > 3) + segment.Leistungserbringergruppe = split[3]; + if (split.Length > 4) + segment.IKAbrechnungsstelle = split[4]; + if (split.Length > 5) + segment.ArtDerDatenlieferung = split[5]; + if (split.Length > 6) + segment.ArtDesÜbermittlungsmediums = split[6]; + if (split.Length > 7) + segment.StandortDesLeistungserbringersNachBundesland = split[7]; + if (split.Length > 8) + segment.StandortDesLeistungserbringersNachKVBezirk = split[8]; + if (split.Length > 9) + segment.Abrechnungscode = split[9]; + if (split.Length > 10) + segment.Tarifkennzeichen = split[10]; + + return segment; + } + } +} diff --git a/Host/Host.csproj.user b/Host/Host.csproj.user index 769cd8b25..a0002e9f5 100644 --- a/Host/Host.csproj.user +++ b/Host/Host.csproj.user @@ -3,7 +3,7 @@ BeWo2.0 true - Release|Any CPU + Debug|Any CPU false