339 lines
10 KiB
C#
339 lines
10 KiB
C#
using BS.Shared.DataContracts;
|
|
using BS.Shared.DataContracts.Invoicing.GkvAbrechnung;
|
|
using BS.Shared.Exceptions;
|
|
using Dakota.Models;
|
|
using Dakota.Models.Nachrichten;
|
|
using Dakota.Models.Segmente.KTD;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
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", "FKT", "VKG", "UNT", "ANS" };
|
|
|
|
internal Dictionary<string, Dictionary<string, NachrichtKTD>> FileDictionary { get; set; }
|
|
= new Dictionary<string, Dictionary<string, NachrichtKTD>>();
|
|
|
|
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 int GetFileCount() => FileDictionary.Count();
|
|
public int GetAllFileEntryCount() => FileDictionary.Sum(x => x.Value.Count);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="ikkrankenkasse"></param>
|
|
/// <param name="abrechnungscode"></param>
|
|
/// <param name="tarifkennzeichen"></param>
|
|
/// <returns>Item1:Datenannahmestelle -
|
|
/// Item2:Kostenträger -
|
|
/// Item3:Krankenkasse</returns>
|
|
public GkvKostentragerdateiSummary Resolve(string ikkrankenkasse, string abrechnungscode, string tarifkennzeichen)
|
|
{
|
|
foreach (var kv in FileDictionary)
|
|
{
|
|
var dict = kv.Value;
|
|
|
|
var search = GetIKNummern(dict, ikkrankenkasse, abrechnungscode, tarifkennzeichen);
|
|
|
|
if (search is object)
|
|
{
|
|
var datenannahmestelle = search.Item1;
|
|
var nachricht = dict[datenannahmestelle];
|
|
|
|
var bez = nachricht.SegmentIDK.Kurzbezeichnung;
|
|
|
|
var sum = new GkvKostentragerdateiSummary()
|
|
{
|
|
BezDatenannahmestelle = bez,
|
|
IKDatenannahmestelle = datenannahmestelle,
|
|
IKKostentrager = search.Item2,
|
|
IKKrankenkasse = search.Item3
|
|
};
|
|
|
|
AddressDC grosskundenanschrift = null;
|
|
foreach (var seg_ans in nachricht.SemgenteANS)
|
|
{
|
|
var address = GetAddress(seg_ans);
|
|
|
|
if (seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Grosskundenanschrift)
|
|
{
|
|
grosskundenanschrift = address;
|
|
}
|
|
else if(seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Postfachanschrift)
|
|
{
|
|
sum.PostfachGKanschrift = address;
|
|
}
|
|
else if(seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Hausanschrift)
|
|
{
|
|
sum.Hausanschrift = address;
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
if (sum.PostfachGKanschrift == null && grosskundenanschrift != null)
|
|
sum.PostfachGKanschrift = grosskundenanschrift;
|
|
|
|
AddressDC hausanschriftPapierannahmestelle = null;
|
|
AddressDC postfachanschriftPapierannahmestelle = null;
|
|
AddressDC grosskundenanschriftPapierannahmestelle = null;
|
|
|
|
var papierIK = GetPapierIK(dict, ikkrankenkasse, abrechnungscode, tarifkennzeichen);
|
|
if (papierIK is object && dict.ContainsKey(papierIK))
|
|
{
|
|
var papierNachricht = dict[papierIK];
|
|
|
|
foreach (var seg_ans in papierNachricht.SemgenteANS)
|
|
{
|
|
var address = GetAddress(seg_ans);
|
|
|
|
if (seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Grosskundenanschrift)
|
|
{
|
|
grosskundenanschriftPapierannahmestelle = address;
|
|
}
|
|
else if (seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Postfachanschrift)
|
|
{
|
|
postfachanschriftPapierannahmestelle = address;
|
|
}
|
|
else if (seg_ans.ArtDerAnschrift == Models.Schlüssels.SchlüsselArtDerAnschrift.Hausanschrift)
|
|
{
|
|
hausanschriftPapierannahmestelle = address;
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
if (hausanschriftPapierannahmestelle != null)
|
|
sum.Papierannahmeanschrift = hausanschriftPapierannahmestelle;
|
|
else if (postfachanschriftPapierannahmestelle != null)
|
|
sum.Papierannahmeanschrift = postfachanschriftPapierannahmestelle;
|
|
else if (grosskundenanschriftPapierannahmestelle != null)
|
|
sum.Papierannahmeanschrift = grosskundenanschriftPapierannahmestelle;
|
|
|
|
if (sum.Papierannahmeanschrift != null)
|
|
sum.Papierannahmeanschrift.AddressLine1 = clear(papierNachricht.SegmentIDK.Kurzbezeichnung);
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private Tuple<string, string, string> GetIKNummern(Dictionary<string, NachrichtKTD> dict, string ikkrankenkasse, string abrechnungscode, string tarifkennzeichen, string kostentrager = null)
|
|
{
|
|
if (kostentrager is null)
|
|
kostentrager = ikkrankenkasse;
|
|
|
|
var search = dict.SingleOrDefault(kv => kv.Key == kostentrager).Value;
|
|
|
|
// Hat keinen Verweis auf eine KK gefunden
|
|
if (search is null)
|
|
return null;
|
|
|
|
var verweis = search.SegmentVKG.FirstOrDefault(x => x.ArtDerVerknüpfung == Models.Schlüssels.SchlüsselArtDerVerknüpfung.Kostentrager);
|
|
|
|
// Hat Verweis auf weiteren Kostenträger gefunden
|
|
if (verweis is object && verweis.IKVerknüpfungspartners != kostentrager)
|
|
return GetIKNummern(dict, ikkrankenkasse, abrechnungscode, tarifkennzeichen, verweis.IKVerknüpfungspartners);
|
|
|
|
var datenannahmestellen = search.SegmentVKG
|
|
.Where(x => x.ArtDerVerknüpfung == Models.Schlüssels.SchlüsselArtDerVerknüpfung.DatenannahmestelleMitEntschlusselungsbefugnis)
|
|
.ToList();
|
|
|
|
// Hat keinen Verweis auf Kostenträger oder Datenannahmestelle gefunden
|
|
if (datenannahmestellen is null || !datenannahmestellen.Any())
|
|
return null;
|
|
|
|
if (datenannahmestellen.Count() == 1)
|
|
return GetIKNummern(datenannahmestellen.First(), kostentrager, ikkrankenkasse);
|
|
|
|
// Abrechnungscode "69" <=> Sozio
|
|
var datenannahmestellen_2 = datenannahmestellen
|
|
.Where(x => x.Abrechnungscode == abrechnungscode)
|
|
.ToList();
|
|
|
|
if (datenannahmestellen_2.Count() == 1)
|
|
return GetIKNummern(datenannahmestellen_2.First(), kostentrager, ikkrankenkasse);
|
|
|
|
// Tarifkennzeichen
|
|
var datenannahmestellen_3 = datenannahmestellen_2
|
|
.Where(x => x.Tarifkennzeichen == tarifkennzeichen)
|
|
.ToList();
|
|
|
|
if (datenannahmestellen_3.Count() == 1)
|
|
return GetIKNummern(datenannahmestellen_3.First(), kostentrager, ikkrankenkasse);
|
|
|
|
// ArtDesÜbermittlungsmediums "1" <=> Datenfernübertragung
|
|
var filter_list = datenannahmestellen_3;
|
|
|
|
if (!filter_list.Any())
|
|
filter_list = datenannahmestellen_2;
|
|
|
|
if (!filter_list.Any())
|
|
filter_list = datenannahmestellen;
|
|
|
|
filter_list = filter_list
|
|
.Where(x => x.ArtDesÜbermittlungsmediums == "1")
|
|
.ToList();
|
|
|
|
if (filter_list.Count() == 1)
|
|
return GetIKNummern(filter_list.First(), kostentrager, ikkrankenkasse);
|
|
|
|
return null;
|
|
}
|
|
|
|
private Tuple<string, string, string> GetIKNummern(SegmentKTDVKG vkg, string kostentrager, string ikkrankenkasse)
|
|
{
|
|
return new Tuple<string, string, string>(vkg.IKVerknüpfungspartners, kostentrager, ikkrankenkasse);
|
|
}
|
|
|
|
private string GetPapierIK(Dictionary<string, NachrichtKTD> dict, string ikkrankenkasse, string abrechnungscode, string tarifkennzeichen, string kostentrager = null)
|
|
{
|
|
if (kostentrager is null)
|
|
kostentrager = ikkrankenkasse;
|
|
|
|
var search = dict.SingleOrDefault(kv => kv.Key == kostentrager).Value;
|
|
|
|
if (search is null)
|
|
return null;
|
|
|
|
var verweis = search.SegmentVKG.FirstOrDefault(x => x.ArtDerVerknüpfung == Models.Schlüssels.SchlüsselArtDerVerknüpfung.Kostentrager);
|
|
|
|
// Hat Verweis auf weiteren Kostenträger gefunden
|
|
if (verweis is object && verweis.IKVerknüpfungspartners != kostentrager)
|
|
return GetPapierIK(dict, ikkrankenkasse, abrechnungscode, tarifkennzeichen, verweis.IKVerknüpfungspartners);
|
|
|
|
var papierannahmestellen = search.SegmentVKG
|
|
.Where(x => x.ArtDerVerknüpfung == Models.Schlüssels.SchlüsselArtDerVerknüpfung.PapierAnnahmestelle)
|
|
.ToList();
|
|
|
|
if (papierannahmestellen is null || !papierannahmestellen.Any())
|
|
return null;
|
|
|
|
if (papierannahmestellen.Count() == 1)
|
|
return papierannahmestellen.First().IKVerknüpfungspartners;
|
|
|
|
// Abrechnungscode
|
|
var filtered = papierannahmestellen
|
|
.Where(x => x.Abrechnungscode == abrechnungscode)
|
|
.ToList();
|
|
|
|
if (filtered.Count() == 1)
|
|
return filtered.First().IKVerknüpfungspartners;
|
|
|
|
// Tarifkennzeichen
|
|
var filtered_2 = filtered
|
|
.Where(x => x.Tarifkennzeichen == tarifkennzeichen)
|
|
.ToList();
|
|
|
|
if (filtered_2.Count() == 1)
|
|
return filtered_2.First().IKVerknüpfungspartners;
|
|
|
|
var filter_list = filtered_2;
|
|
|
|
if (!filter_list.Any())
|
|
filter_list = filtered;
|
|
|
|
if (!filter_list.Any())
|
|
filter_list = papierannahmestellen;
|
|
|
|
if (filter_list.Count() == 1)
|
|
return filter_list.First().IKVerknüpfungspartners;
|
|
|
|
return null;
|
|
}
|
|
|
|
private AddressDC GetAddress(SegmentKTDANS segment)
|
|
{
|
|
var address = new AddressDC();
|
|
|
|
address.Street = clear(segment.StraßeHausnummerOderPostfach);
|
|
address.Town = clear(segment.Ort);
|
|
address.PostalCode = clear(segment.Postleitzahl);
|
|
|
|
return address;
|
|
}
|
|
|
|
private string clear(string str)
|
|
{
|
|
if (str is null)
|
|
return null;
|
|
string asciiOnly = new string(str.Where(c => c <= 127).ToArray());
|
|
return asciiOnly;
|
|
}
|
|
|
|
private void foo(string filename, string[] lines)
|
|
{
|
|
var length = lines.Length;
|
|
var dict = new Dictionary<string, NachrichtKTD>();
|
|
|
|
FileDictionary.Add(filename, dict);
|
|
|
|
Queue<string> queue = new Queue<string>();
|
|
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")
|
|
{
|
|
var nachricht = NachrichtKTD.Parse(queue.ToArray(), filename, first_line);
|
|
|
|
if (dict.ContainsKey(nachricht.IKNummer))
|
|
throw new Exception($"Beinhaltet Key bereits: {nachricht.IKNummer} in {filename} - l {first_line}");
|
|
|
|
dict.Add(nachricht.IKNummer, nachricht);
|
|
|
|
queue.Clear();
|
|
}
|
|
else
|
|
{
|
|
queue.Enqueue(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
private string GetType(string line)
|
|
{
|
|
var type = line.Substring(0, 3);
|
|
|
|
return accept.Contains(type) ? type : null;
|
|
}
|
|
}
|
|
}
|