diff --git a/Dakota/DakotaValidator.cs b/Dakota/DakotaValidator.cs
index 2edfd956e..622ba6b0b 100644
--- a/Dakota/DakotaValidator.cs
+++ b/Dakota/DakotaValidator.cs
@@ -1,4 +1,5 @@
-using BS.Shared.DataContracts;
+using BeWo.Data.Entities;
+using BS.Shared.DataContracts;
using BS.Shared.DataContracts.GkvAbrechnung;
using Dakota.Models;
using System;
@@ -47,34 +48,23 @@ namespace Dakota
throw new DakotaException(error);
}
- public static void ValidateOrganisation(OrganisationDC orgadc)
+ public static void ValidateOrganisation(Organisation orga)
{
string error = null;
- if (orgadc == null)
+ if (orga == null)
error = "Organisation ist null";
-
- if (!ValidateIKNumbers(orgadc))
- {
-
- }
-
-
- //if (!ValidateIKNumber(orgadc.IKDatenannahmestelle))
- // error = $"Die Organisation \"{orgadc.Name}\" hat keine gültige IK Nummer für die Datenannahmestelle.";
- //else if (!ValidateIKNumber(orgadc.IKKostentrager))
- // error = $"Die Organisation \"{orgadc.Name}\" hat keine gültige IK Nummer für die Kostenträger.";
- //else if (!ValidateIKNumber(orgadc.IKKrankenkasse))
- // error = $"Die Organisation \"{orgadc.Name}\" hat keine gültige IK Nummer für die Krankenkasse.";
- if (!ValidateLeistungserbringergruppe(orgadc.Leistungserbringergruppe))
- error = $"Die Organisation \"{orgadc.Name}\" hat keine gültige Leistungserbringergruppe: \"{orgadc.Leistungserbringergruppe}\". Erwarten werden 5 Stellen für das Tarifkennzeichen alleine oder 7 Stellen für den Abrechnungscode und für das Tarifkennzeichen zusammen.";
+ else if (!ValidateLeistungserbringergruppe(orga.Leistungserbringergruppe))
+ error = $"Die Organisation \"{orga.Name}\" hat keine gültige Leistungserbringergruppe: \"{orga.Leistungserbringergruppe}\". Erwarten werden 5 Stellen für das Tarifkennzeichen alleine oder 7 Stellen für den Abrechnungscode und für das Tarifkennzeichen zusammen.";
+ else if (!ValidateIKNumber(orga.IKKrankenkasse))
+ error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Kennzeichen: \"{orga.IKKrankenkasse}\".";
if (error != null)
throw new DakotaException(error);
}
- private static bool ValidateIKNumbers(OrganisationDC dc)
- => ValidateIKNumbers(dc.IKDatenannahmestelle, dc.IKKostentrager, dc.IKKrankenkasse);
+ public static bool ValidateIKNumbers(Organisation orga)
+ => ValidateIKNumbers(orga.IKDatenannahmestelle, orga.IKKostentrager, orga.IKKrankenkasse);
private static bool ValidateIKNumbers(params string[] iks)
=> iks?.All(ValidateIKNumber) ?? false;
diff --git a/Dakota/Logic/DakotaKTDReader.cs b/Dakota/Logic/DakotaKTDReader.cs
index 76ae81e19..310866b2f 100644
--- a/Dakota/Logic/DakotaKTDReader.cs
+++ b/Dakota/Logic/DakotaKTDReader.cs
@@ -33,9 +33,17 @@ namespace Dakota.Logic
}
public int GetFileCount() => FileDictionary.Count();
-
public int GetAllFileEntryCount() => FileDictionary.Sum(x => x.Value.Count);
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Item1:Datenannahmestelle -
+ /// Item2:Kostenträger -
+ /// Item3:Krankenkasse
public Tuple Resolve(string ikkrankenkasse, string abrechnungscode, string tarifkennzeichen)
{
foreach (var kv in FileDictionary)
diff --git a/Dakota/Logic/DakotaUtils.cs b/Dakota/Logic/DakotaUtils.cs
index 98704fc5b..e8fe2b5df 100644
--- a/Dakota/Logic/DakotaUtils.cs
+++ b/Dakota/Logic/DakotaUtils.cs
@@ -43,5 +43,42 @@ namespace Dakota.Logic
return sb.ToString();
}
+
+ public static string GetAbrechnungscode(string leistungserbringergruppe)
+ {
+ var len = leistungserbringergruppe.Length;
+
+ if(len == 5)
+ {
+ return "69";
+ }
+ else if(len == 7)
+ {
+ return leistungserbringergruppe.Substring(0, 2);
+ }
+ else
+ {
+ throw new ArgumentException($"Leistungserbringergruppe \"{leistungserbringergruppe}\" hat ungültige Anzahl Stellen");
+ }
+ }
+
+ public static string GetTarifkennzeichen(string leistungserbringergruppe)
+ {
+ var len = leistungserbringergruppe.Length;
+
+ if (len == 5)
+ {
+ return leistungserbringergruppe;
+ }
+ else if (len == 7)
+ {
+ return leistungserbringergruppe.Substring(2);
+ // return leistungserbringergruppe.Substring(2, 5);
+ }
+ else
+ {
+ throw new ArgumentException($"Leistungserbringergruppe \"{leistungserbringergruppe}\" hat ungültige Anzahl Stellen");
+ }
+ }
}
}
diff --git a/DakotaUnitTest/DakotaReaderUnitTest.cs b/DakotaUnitTest/DakotaReaderUnitTest.cs
index 0fd8f548f..450fcf68d 100644
--- a/DakotaUnitTest/DakotaReaderUnitTest.cs
+++ b/DakotaUnitTest/DakotaReaderUnitTest.cs
@@ -54,5 +54,19 @@ namespace DakotaUnitTest
Assert.IsTrue(test.Item3 == "105328415");
}
+
+ [TestMethod]
+ public void ValidateAOKRheinlandHamburgSoz()
+ {
+ var test = Reader.Resolve("104212505", "69", "00000");
+
+ Assert.IsNotNull(test);
+
+ Assert.IsTrue(test.Item1 == "104212516");
+
+ Assert.IsTrue(test.Item2 == "104212505");
+
+ Assert.IsTrue(test.Item3 == "104212505");
+ }
}
}
diff --git a/Data/Entities/GkvAbrechnung.cs b/Data/Entities/GkvAbrechnung.cs
index 72cae06a4..bcfff7ee6 100644
--- a/Data/Entities/GkvAbrechnung.cs
+++ b/Data/Entities/GkvAbrechnung.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-
+using System.Linq;
using BS.Shared;
using BS.Shared.Extensions;
@@ -31,5 +31,10 @@ namespace BeWo.Data.Entities
(x) => x.Fehlerdatum,
(x) => x.Fehlerlevel,
(x) => x.ErstelltAm.Value);
+
+ public virtual Organisation GetOrganisation()
+ {
+ return InvoiceBases.First().CostBearer2SupportConcept.CostBearer.Organisation;
+ }
}
}
\ No newline at end of file
diff --git a/Host/GkvAbrechnungView.aspx.cs b/Host/GkvAbrechnungView.aspx.cs
index 29840075b..4067700aa 100644
--- a/Host/GkvAbrechnungView.aspx.cs
+++ b/Host/GkvAbrechnungView.aspx.cs
@@ -32,6 +32,7 @@ using System.Xml;
using System.Xml.Linq;
using System.Diagnostics;
using System.Xml.Serialization;
+using Dakota.Logic;
namespace Host
{
@@ -44,6 +45,7 @@ namespace Host
private string ResultFolderPath { get; set; } = ConfigurationManager.AppSettings.Get("GkvAbrechnungResultFolderPath");
private string QueueFolderPath { get; set; } = ConfigurationManager.AppSettings.Get("GkvAbrechnungQueueFolderPath");
+ private string KostentragerdateiFolderPath { get; set; } = ConfigurationManager.AppSettings.Get("GkvKostentragerdateiFolderPath");
public GkvApp8Request GkvRequest { get; set; }
@@ -253,14 +255,21 @@ namespace Host
}
private void GetIK(GkvApp8GetIKRequest req)
{
- var input = req.KrankenkassenIK;
+ var ktd_reader = new DakotaKTDReader(KostentragerdateiFolderPath);
+
+ var resolved = ktd_reader.Resolve(req.IKKrankenkasse, req.Abrechnungscode, req.Tarifkennzeichen);
var response = new GkvApp8GetIKResponse();
response.Success = true;
- response.IKVersichertenKarte = input;
- response.IKDatenannahmestelle = "111222333";
- response.IKKostenträger = "333444555";
+ response.Gefunden = resolved is object;
+
+ if (response.Gefunden)
+ {
+ response.IKDatenannahmestelle = resolved.Item1;
+ response.IKKostentrager = resolved.Item2;
+ response.IKKrankenkasse = resolved.Item3;
+ }
SendResponse(response);
}
diff --git a/Service/DCEntityMapper/GkvAbrechnungDC_GkvAbrechnung.cs b/Service/DCEntityMapper/GkvAbrechnungDC_GkvAbrechnung.cs
index 19b75f4cc..ded8c603f 100644
--- a/Service/DCEntityMapper/GkvAbrechnungDC_GkvAbrechnung.cs
+++ b/Service/DCEntityMapper/GkvAbrechnungDC_GkvAbrechnung.cs
@@ -17,7 +17,7 @@ namespace BeWo.Service.DCEntityMapper
{
}
- var orga = pEntity.InvoiceBases.First().CostBearer2SupportConcept.CostBearer.Organisation;
+ var orga = pEntity.GetOrganisation();
pDataContract.GkvAbrechnungOid = pEntity.Oid;
pDataContract.GkvAbrechnungVersion = pEntity.Version;
diff --git a/Service/ServiceImplementations/AccountingServiceImp.cs b/Service/ServiceImplementations/AccountingServiceImp.cs
index d7ea5557c..26c5d0749 100644
--- a/Service/ServiceImplementations/AccountingServiceImp.cs
+++ b/Service/ServiceImplementations/AccountingServiceImp.cs
@@ -566,7 +566,7 @@ namespace BeWo.Service.ServiceImplementations
{
var dc = invoices.Where(i => i.InvoiceBaseOid == entity.Oid).FirstOrDefault();
-
+
if (dc.IsPaid != entity.IsPaid ||
dc.IsExported != entity.IsExported ||
dc.IsReviewed != entity.IsReviewed ||
@@ -718,7 +718,6 @@ namespace BeWo.Service.ServiceImplementations
throw Utils.CreateBeWoFaultException(e);
}
}
-
public List GetFilteredGkvAbrechnungen(GkvAbrechnungViewFilterDC gkvAbrechnungViewFilter)
{
try
@@ -739,7 +738,6 @@ namespace BeWo.Service.ServiceImplementations
throw Utils.CreateBeWoFaultException(e);
}
}
-
public List GetAllGkvAbrechnungen()
{
try
@@ -755,7 +753,7 @@ namespace BeWo.Service.ServiceImplementations
if (!updateables.Any())
return dcs;
- var isUpToDate = SendApp8GetStatusRequest(updateables, user.LoginName, user.BCryptPassword);
+ var isUpToDate = SendApp8GetStatusRequest(updateables);
if (isUpToDate)
return dcs;
@@ -829,7 +827,6 @@ namespace BeWo.Service.ServiceImplementations
return response;
}
-
public GkvAbrechnungDC UpdateGkvAbrechnung(GkvAbrechnungDC abrechnung)
{
try
@@ -847,7 +844,6 @@ namespace BeWo.Service.ServiceImplementations
throw Utils.CreateBeWoFaultException(e);
}
}
-
public void DeleteGkvAbrechnung(GkvAbrechnungDC abrechnung)
{
try
@@ -866,16 +862,18 @@ namespace BeWo.Service.ServiceImplementations
response.Successful = false;
- var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
- if (user == null)
+ var oid = req.GkvAbrechnungOid;
+
+ var entity = DAOFactory.GenericDAO.LoadByID(oid);
+
+ var state = GkvAbrechnung.GetState(entity);
+
+ if (state == GkvState.Waiting || state == GkvState.OldAndNoFeedback || state == GkvState.Paid)
{
- response.Message = "User unbekannt";
+ response.Message = "Validierung fehlgeschlagen";
return response;
}
- var oid = req.GkvAbrechnungOid;
- var entity = DAOFactory.GenericDAO.LoadByID(oid);
-
var protokoll = new GkvTransferProtokoll();
protokoll.ErstelltAm = DateTime.Now;
@@ -883,22 +881,17 @@ namespace BeWo.Service.ServiceImplementations
try
{
- var validation_success = CreateGkvTransferProtokoll(entity, protokoll);
-
- if(!validation_success)
- {
- response.Message = "Validierung fehlgeschlagen";
- return response;
- }
+ CreateGkvTransferProtokoll(oid, entity, protokoll);
if (entity.GkvTransferProtokolle is null)
entity.GkvTransferProtokolle = new List();
entity.GkvTransferProtokolle.Add(protokoll);
+ // Protokoll braucht Oid
DAOFactory.GenericDAO.Update(entity);
- var app8_response = SendApp8SendNewRequest(protokoll, user.LoginName, user.BCryptPassword);
+ var app8_response = SendApp8SendNewRequest(protokoll);
var app8_protokoll = app8_response.GkvTransferProtokollDC;
@@ -928,8 +921,7 @@ namespace BeWo.Service.ServiceImplementations
return response;
}
-
- private bool CreateGkvTransferProtokoll(GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll)
+ private void CreateGkvTransferProtokoll(long oid, GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll)
{
try
{
@@ -938,19 +930,38 @@ namespace BeWo.Service.ServiceImplementations
DakotaValidator.ValidateMandator(mandatordc);
+ var orga = gkvAbrechnung.GetOrganisation();
+
+ DakotaValidator.ValidateOrganisation(orga);
+
+ if (!DakotaValidator.ValidateIKNumbers(orga))
+ {
+ var res = SendApp8GetIKRequest(orga);
+
+ if (!res.Success)
+ throw new DakotaException(res.Message, "Interner Fehler");
+
+ if (!res.Gefunden)
+ throw new DakotaException($"Für die Organisation \"{orga.Name}\" mit dem IK \"{orga.IKKrankenkasse}\" konnte keine Datenannahmestelle gefunden werden. " +
+ $"Bitte informieren Sie sich bei der Krankenkasse, ob zum elektronischen Datenaustausch " +
+ $"eine seperate Anmeldung benötigt wird.");
+
+ orga.IKDatenannahmestelle = res.IKDatenannahmestelle;
+ orga.IKKostentrager = res.IKKostentrager;
+ // orgadc.IKKrankenkasse = res.IKKrankenkasse;
+
+ if (!DakotaValidator.ValidateIKNumbers(orga))
+ throw new DakotaException($"Für die Organisation \"{orga.Name}\" konnten die hinterlegten IKs nicht verifiziert werden: \"{orga.IKDatenannahmestelle}\", \"{orga.IKKostentrager}\", \"{orga.IKKrankenkasse}\"", "Interner Fehler");
+
+ DAOFactory.GenericDAO.Update(orga);
+
+ gkvAbrechnung = DAOFactory.GenericDAO.LoadByID(oid);
+ }
+
var gkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkvAbrechnung);
var orgadc = gkvAbrechnungDC.Organisation;
- DakotaValidator.ValidateOrganisation(orgadc);
-
- var state = GkvAbrechnung.GetState(gkvAbrechnung);
-
- if (state == GkvState.Waiting || state == GkvState.OldAndNoFeedback || state == GkvState.Paid)
- {
- return false;
- }
-
- var datenannahmestelle = gkvAbrechnungDC.Organisation.IKDatenannahmestelle;
+ var datenannahmestelle = orgadc.IKDatenannahmestelle;
var (datenaustauschreferenz, transfernummer) = GetNextDatenaustauschreferenzTransfernummer(gkvAbrechnung, datenannahmestelle);
var (dat_short, tra_short) = ClearDatenaustauschreferenzTransfernummer(datenaustauschreferenz, transfernummer);
@@ -1010,8 +1021,6 @@ namespace BeWo.Service.ServiceImplementations
protokoll.AbsenderBezeichnung = "TestAbsBez";
protokoll.EmpfangerBezeichnung = "TestEmpBez";
-
- return true;
}
catch (DakotaException de)
{
@@ -1048,7 +1057,6 @@ namespace BeWo.Service.ServiceImplementations
return new Tuple(datenaustauschref, transfernummer);
}
-
private Tuple ClearDatenaustauschreferenzTransfernummer(int datenaustauschreferenz, int transfernummer)
{
int d = datenaustauschreferenz % 99999;
@@ -1062,7 +1070,7 @@ namespace BeWo.Service.ServiceImplementations
return new Tuple(d, t);
}
- private GkvApp8SendNewResponse SendApp8SendNewRequest(GkvTransferProtokoll protokoll, string loginName, string hashed_password)
+ private GkvApp8SendNewResponse SendApp8SendNewRequest(GkvTransferProtokoll protokoll)
{
var gkv_transfer_dc = MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MapToNewDC(protokoll);
@@ -1075,20 +1083,14 @@ namespace BeWo.Service.ServiceImplementations
var request_app8 = new GkvApp8SendNewRequest
{
SendDirect = true,
- GkvTransferProtokoll = gkv_transfer_dc,
- Username = loginName,
- Password = hashed_password,
- Tenant = MultitenancyOperationContextExt.Current.Tenant,
- DebugMode = "fozc4897b6ztvf978AFCRRG244fvFV2532fvf324AF"
+ GkvTransferProtokoll = gkv_transfer_dc
};
#if DEBUG
request_app8.SendDirect = false;
#endif
- var response_app8_str = SendApp8Request(url, request_app8);
-
- var response_app8 = JsonConvert.DeserializeObject(response_app8_str);
+ var response_app8 = SendApp8Request(url, request_app8);
if (!response_app8.Success)
throw new DakotaException(response_app8.Message);
@@ -1102,7 +1104,7 @@ namespace BeWo.Service.ServiceImplementations
///
///
/// Returns true, if the states are all up to date. False otherwise.
- private bool SendApp8GetStatusRequest(GkvAbrechnungDC[] updateables, string loginName, string hashed_password)
+ private bool SendApp8GetStatusRequest(GkvAbrechnungDC[] updateables)
{
var updateables_len = updateables.Count();
@@ -1110,8 +1112,6 @@ namespace BeWo.Service.ServiceImplementations
var request = new GkvApp8GetStatusRequest
{
- Username = loginName,
- Password = hashed_password,
Tenant = MultitenancyOperationContextExt.Current.Tenant,
Oids = new long[updateables_len],
DebugMode = "fozc4897b6ztvf978AFCRRG244fvFV2532fvf324AF",
@@ -1128,18 +1128,16 @@ namespace BeWo.Service.ServiceImplementations
GkvApp8GetStatusResponse response_app8;
try
{
- var response_app8_str = SendApp8Request(url, JsonConvert.SerializeObject(request));
-
- response_app8 = JsonConvert.DeserializeObject(response_app8_str);
+ response_app8 = SendApp8Request(url, request);
}
- catch(Exception e)
+ catch (Exception e)
{
return true;
}
if (!response_app8.Success)
throw new DakotaException(response_app8.Message);
-
+
bool allAreUpToDate = true;
for (int id = 0; id < updateables_len; id++)
{
@@ -1166,7 +1164,39 @@ namespace BeWo.Service.ServiceImplementations
return allAreUpToDate;
}
- private string SendApp8Request(string url, object request) => SendApp8Request(url, JsonConvert.SerializeObject(request));
+ private GkvApp8GetIKResponse SendApp8GetIKRequest(Organisation orga)
+ {
+ var gruppe = orga.Leistungserbringergruppe;
+ var abr = DakotaUtils.GetAbrechnungscode(gruppe);
+ var tarif = DakotaUtils.GetTarifkennzeichen(gruppe);
+
+ var url = "https://app8.bewoplaner.de/service/GkvAbrechnungView.aspx";
+
+ var request = new GkvApp8GetIKRequest
+ {
+ Abrechnungscode = abr,
+ IKKrankenkasse = orga.IKKrankenkasse,
+ Tarifkennzeichen = tarif
+ };
+
+ return SendApp8Request(url, request);
+ }
+
+ private T2 SendApp8Request(string url, T request) where T : GkvApp8Request where T2 : GkvApp8Response
+ {
+ var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
+ if (user == null)
+ {
+ throw new DakotaException("User unbekannt", "KApp");
+ }
+
+ request.Username = user.LoginName;
+ request.Password = user.BCryptPassword;
+ request.DebugMode = "fozc4897b6ztvf978AFCRRG244fvFV2532fvf324AF";
+ request.Tenant = MultitenancyOperationContextExt.Current.Tenant;
+
+ return JsonConvert.DeserializeObject(SendApp8Request(url, JsonConvert.SerializeObject(request)));
+ }
private string SendApp8Request(string url, string dataString)
{
string response_app8_str;
@@ -1182,7 +1212,7 @@ namespace BeWo.Service.ServiceImplementations
response_app8_str = client.UploadString(url, "POST", dataString);
}
}
- catch(Exception e)
+ catch (Exception e)
{
throw new DakotaException(e.Message, "App8");
}
diff --git a/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKRequest.cs b/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKRequest.cs
index 14167ce89..751c81fd4 100644
--- a/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKRequest.cs
+++ b/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKRequest.cs
@@ -10,7 +10,13 @@ namespace BS.Shared.DataContracts.GkvAbrechnung
public class GkvApp8GetIKRequest : GkvApp8Request
{
[DataMember]
- public string KrankenkassenIK { get; set; }
+ public string IKKrankenkasse { get; set; }
+
+ [DataMember]
+ public string Abrechnungscode { get; set; }
+
+ [DataMember]
+ public string Tarifkennzeichen { get; set; }
public GkvApp8GetIKRequest()
{
diff --git a/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKResponse.cs b/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKResponse.cs
index e07dfc7b4..75a06cef3 100644
--- a/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKResponse.cs
+++ b/Shared/DataContracts/GkvAbrechnung/GkvApp8GetIKResponse.cs
@@ -10,10 +10,13 @@ namespace BS.Shared.DataContracts.GkvAbrechnung
public class GkvApp8GetIKResponse : GkvApp8Response
{
[DataMember]
- public string IKVersichertenKarte { get; set; }
+ public bool Gefunden { get; set; }
[DataMember]
- public string IKKostenträger { get; set; }
+ public string IKKrankenkasse { get; set; }
+
+ [DataMember]
+ public string IKKostentrager { get; set; }
[DataMember]
public string IKDatenannahmestelle { get; set; }