diff --git a/BeWo/View/Detail/Accounting/GkvAbrechnungOverview.xaml.cs b/BeWo/View/Detail/Accounting/GkvAbrechnungOverview.xaml.cs index 0cbac3eb2..190589b6b 100644 --- a/BeWo/View/Detail/Accounting/GkvAbrechnungOverview.xaml.cs +++ b/BeWo/View/Detail/Accounting/GkvAbrechnungOverview.xaml.cs @@ -140,11 +140,13 @@ namespace BeWo.View.Detail.Accounting MainControl.CloseCurrentPopUp(); var gkv_abrechnung = e.Data; - var gkv_filter = new GkvAbrechnungCreateRequestDC(gkv_abrechnung); + var gkv_filter = new GkvAbrechnungCreateRequestDC + { + GkvAbrechnungDC = gkv_abrechnung, + SelectedInvoiceBases = checked_invoice_bases.Select(x => x.DataContract.InvoiceBaseOid.Value).ToList() + }; - gkv_filter.SelectedInvoiceBases = checked_invoice_bases.Select(x => x.DataContract.InvoiceBaseOid.Value).ToList(); - - ServiceFacade.DoAccountingServiceAsync(x => x.CreateNewGkvAbrechnung(gkv_filter), + ServiceFacade.DoAccountingServiceAsync(x => x.CreateNewGkvAbrechnung(gkv_filter), cb => Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate { @@ -154,7 +156,7 @@ namespace BeWo.View.Detail.Accounting } else { - BeWoWindowBuilder.ShowErrorMessageBox(cb.Error); + BeWoWindowBuilder.ShowErrorMessageBox(cb.Message); } })); } diff --git a/Dakota/DakotaUtils.cs b/Dakota/DakotaUtils.cs index e5eb342cc..40c92c1b1 100644 --- a/Dakota/DakotaUtils.cs +++ b/Dakota/DakotaUtils.cs @@ -2,6 +2,7 @@ using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.GkvAbrechnung; +using BS.Shared.Exceptions; using Dakota.Models; using System; using System.Collections.Generic; @@ -95,54 +96,5 @@ namespace Dakota return input.Trim(); } - - /// - /// Validiert in erster Phase den Mandator. - /// - public static void ValidateMandator(MandatorDC mandatordc) - { - if (mandatordc == null) - throw new DakotaException("Mandator ist null"); - - if (!DakotaValidator.IsIKNumberValid(mandatordc.IKLeistungserbringer)) - throw new DakotaException($"Die IK Nummer des Leistungserbringers \"{mandatordc.IKLeistungserbringer}\" ist ungültig."); - } - - /// - /// Validiert in zweiter Phase die Daten. Bei Fehler wird eine DakotaException geworfen. - /// - public static void ValidateCustomer(CustomerDC customerDC) - { - string error = null; - - if (customerDC == null) - error = "Customer ist null"; - else if (!DakotaValidator.IsVersichertennummerValid(customerDC.InsuranceNumber)) - error = $"Klient/in \"{customerDC.LastName}, {customerDC.FirstName}\" hat keine gültige Versichertennummer"; - else if (!DakotaValidator.IsVersichertenstatusValid(customerDC.VersichertenStatus)) - error = $"Klient/in \"{customerDC.LastName}, {customerDC.FirstName}\" hat keinen gültigen Versichertenstatus"; - - if (error != null) - throw new DakotaException(error); - } - - public static void ValidateOrganisation(Organisation orga) - { - string error = null; - - if (orga == null) - error = "Organisation ist null"; - else if (!DakotaValidator.IsLeistungserbringergruppeValid(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 (!DakotaValidator.IsIKNumberValid(orga.IKKrankenkasse)) - error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Krankenkasse Kennzeichen: \"{orga.IKKrankenkasse}\"."; - else if (!DakotaValidator.IsIKNumberValid(orga.IKKostentrager)) - error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Kostenträger Kennzeichen: \"{orga.IKKostentrager}\"."; - else if (!DakotaValidator.IsIKNumberValid(orga.IKDatenannahmestelle)) - error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Datenannahmestelle Kennzeichen: \"{orga.IKDatenannahmestelle}\"."; - - if (error != null) - throw new DakotaException(error); - } } } diff --git a/Dakota/Logic/DakotaKTDReader.cs b/Dakota/Logic/DakotaKTDReader.cs index 27af3edcb..dfe682541 100644 --- a/Dakota/Logic/DakotaKTDReader.cs +++ b/Dakota/Logic/DakotaKTDReader.cs @@ -1,4 +1,5 @@ -using Dakota.Models; +using BS.Shared.Exceptions; +using Dakota.Models; using Dakota.Models.Nachrichten; using Dakota.Models.Segmente.KTD; using System; @@ -102,7 +103,7 @@ namespace Dakota.Logic if (datenannahmestellen_3.Count() == 1) return GetIKNummern(datenannahmestellen_3.First(), kostentrager, ikkrankenkasse); - throw new DakotaException($"Keine oder mehrere Datenannahmestellen für {ikkrankenkasse} gefunden."); + throw new GkvException($"Keine oder mehrere Datenannahmestellen für {ikkrankenkasse} gefunden."); } private Tuple GetIKNummern(SegmentKTDVKG vkg, string kostentrager, string ikkrankenkasse) diff --git a/Dakota/Models/Daten/Datenelement.cs b/Dakota/Models/Daten/Datenelement.cs index f448ce627..2ec640609 100644 --- a/Dakota/Models/Daten/Datenelement.cs +++ b/Dakota/Models/Daten/Datenelement.cs @@ -1,4 +1,5 @@ -using Dakota.Models.Schlüssels; +using BS.Shared.Exceptions; +using Dakota.Models.Schlüssels; using System; namespace Dakota.Models.Daten @@ -36,7 +37,7 @@ namespace Dakota.Models.Daten if (Feldart == Feldart.Muss) { // Auffüllen - throw new DakotaException($"Das Feld \"{Title}\" muss gefüllt sein!"); + throw new GkvException($"Das Feld \"{Title}\" muss gefüllt sein!"); } else { @@ -50,11 +51,11 @@ namespace Dakota.Models.Daten { if(_Value.Length < MinStellen) { - throw new DakotaException($"Das Feld \"{Title}\" hat bei der Auswertung {_Value.Length} Stellen ergeben! Nach Vorgabe muss es jedoch mindestens {MinStellen} Stellen haben"); + throw new GkvException($"Das Feld \"{Title}\" hat bei der Auswertung {_Value.Length} Stellen ergeben! Nach Vorgabe muss es jedoch mindestens {MinStellen} Stellen haben"); } else if (_Value.Length > MaxStellen) { - throw new DakotaException($"Das Feld \"{Title}\" hat bei der Auswertung {_Value.Length} Stellen ergeben! Nach Vorgabe darf es jedoch maximal {MaxStellen} Stellen haben"); + throw new GkvException($"Das Feld \"{Title}\" hat bei der Auswertung {_Value.Length} Stellen ergeben! Nach Vorgabe darf es jedoch maximal {MaxStellen} Stellen haben"); } } @@ -89,12 +90,12 @@ namespace Dakota.Models.Daten if (value.Length < MinStellen) { - throw new DakotaException($"Das Feld \"{Title}\" hat bei der Erstellung {_Value.Length} Stellen ergeben! Nach Vorgabe muss es jedoch mindestens {MinStellen} Stellen haben"); + throw new GkvException($"Das Feld \"{Title}\" hat bei der Erstellung {_Value.Length} Stellen ergeben! Nach Vorgabe muss es jedoch mindestens {MinStellen} Stellen haben"); } if (value.Length > MaxStellen) { - throw new DakotaException($"Das Feld \"{Title}\" hat bei der Erstellung {_Value.Length} Stellen ergeben! Nach Vorgabe darf es jedoch maximal {MaxStellen} Stellen haben"); + throw new GkvException($"Das Feld \"{Title}\" hat bei der Erstellung {_Value.Length} Stellen ergeben! Nach Vorgabe darf es jedoch maximal {MaxStellen} Stellen haben"); } var mod_value = DakotaUtils.ClearTextString(value); diff --git a/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs b/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs index 020199737..36e18eb49 100644 --- a/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs +++ b/Dakota/Models/Schlüssels/SchlüsselKTDVerarbeitungskennzeichen.cs @@ -1,4 +1,5 @@ -using BS.Shared.Extensions; +using BS.Shared.Exceptions; +using BS.Shared.Extensions; using System; using System.Collections.Generic; using System.Linq; @@ -27,7 +28,7 @@ namespace Dakota.Models.Schlüssels var schlüssel = GetSchlüssel(list, str); if (schlüssel is null) - throw new DakotaException($"KTDVerarbeitungskennzeichen {str} nicht gefunden."); + throw new GkvException($"KTDVerarbeitungskennzeichen {str} nicht gefunden."); return schlüssel; } diff --git a/DakotaSender/Program.cs b/DakotaSender/Program.cs index 7e73d9847..a98a0825a 100644 --- a/DakotaSender/Program.cs +++ b/DakotaSender/Program.cs @@ -156,6 +156,7 @@ namespace DakotaSender var datenannahmestelle = split[2]; var transfername = split[3]; + // Muss nachher nur entfernt werden, um andere zu testen if (tenant != TEST_TENANT && tenant != "demo") { PrintLine($"{auft.FullName} wird ignoriert. Tenant {tenant} nicht gültig."); diff --git a/Data/ASPHibernateSessionManager.cs b/Data/ASPHibernateSessionManager.cs index 5ca064459..8880b5f0c 100644 --- a/Data/ASPHibernateSessionManager.cs +++ b/Data/ASPHibernateSessionManager.cs @@ -74,7 +74,10 @@ namespace BeWo.Data if (string.IsNullOrEmpty(context.Request.FilePath)) return false; - if (context.Request.FilePath.IndexOf("GkvAbrechnungView.aspx") >= 0) + if (context.Request.FilePath.IndexOf("GkvAbrechnungServer.aspx") >= 0) + return false; + + if (context.Request.FilePath.IndexOf("GkvAbrechnungClient.aspx") >= 0) return false; if (context.Request.FilePath.IndexOf("Admin.aspx") >= 0) diff --git a/Host/GkvAbrechnungClient.aspx.cs b/Host/GkvAbrechnungClient.aspx.cs index 06de97060..c23994c0e 100644 --- a/Host/GkvAbrechnungClient.aspx.cs +++ b/Host/GkvAbrechnungClient.aspx.cs @@ -1,10 +1,13 @@ -using BS.Shared; +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BS.Shared; using BS.Shared.AppSender; using BS.Shared.DataContracts.GkvAbrechnung; using BS.Shared.Exceptions; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Configuration; using System.IO; using System.Linq; using System.Threading; @@ -18,6 +21,8 @@ namespace Host { private readonly string INVALID_INPUT = "Ungültige Eingabe"; + private string GkvSecretKey { get; set; } = ConfigurationManager.AppSettings.Get("GkvSecretKey"); + public GkvRequestDC GkvRequest { get; set; } public void Sleep() => Thread.Sleep(5000); @@ -53,15 +58,18 @@ namespace Host } } - - private void ClientResult(GkvClientResultRequestDC req) { + if (GkvSecretKey != req.GkvSecretKey) + SendInvalidInputResponse(); + // Response - var response = new GkvResponseDC(false, "default"); + var response = new GkvResponseDC(false); try { + var fehler_protokoll = DAOFactory.GenericDAO.GetByID(req.Protokoll_Fehler_Oid); + response.Success = true; } catch (GkvException e) diff --git a/Host/GkvAbrechnungServer.aspx.cs b/Host/GkvAbrechnungServer.aspx.cs index d23f071d6..a2fb7bd6c 100644 --- a/Host/GkvAbrechnungServer.aspx.cs +++ b/Host/GkvAbrechnungServer.aspx.cs @@ -22,15 +22,13 @@ namespace Host { public const int PROCESS_WAITFOREXIT_MS = 10 * 1000; - private readonly string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0"; private readonly string LOGINSERVER_URL = "{0}/Login.aspx"; private readonly string INVALID_INPUT = "Ungültige Eingabe"; - 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 GkvRequestDC GkvRequest { get; set; } protected void Page_Load(object sender, EventArgs e) @@ -99,7 +97,7 @@ namespace Host } private bool TryLogin(GkvRequestDC req) { - var server = GetServerFromTenant(req.Tenant); + var server = AppRequestSender.GetServerFromTenant(req.Tenant); if (string.IsNullOrEmpty(server)) return false; @@ -141,7 +139,7 @@ namespace Host private void SendNew(GkvServerSendNewRequestDC req) { // Response - var response = new GkvServerSendNewResponseDC(false); + var response = new GkvServerSendNewResponseDC(); var protokoll = req.GkvTransferProtokoll; @@ -182,10 +180,10 @@ namespace Host var resolved = ktd_reader.Resolve(req.IKKrankenkasse, req.Abrechnungscode, req.Tarifkennzeichen); - var response = new GkvServerGetIKResponseDC(); - - response.Success = true; - response.Gefunden = resolved is object; + var response = new GkvServerGetIKResponseDC(true) + { + Gefunden = resolved is object + }; if (response.Gefunden) { @@ -203,7 +201,7 @@ namespace Host var tuple_count = req.Oids.Length; - response.Result = new GkvApp8ResultDC[tuple_count]; + response.ResultDC = new GkvServerResultDC[tuple_count]; try { @@ -217,7 +215,7 @@ namespace Host if (results.TryGetValue(gkv_transfer_oid, out var fehlerDC)) { - response.Result[i] = fehlerDC; + response.ResultDC[i] = fehlerDC; } } @@ -225,7 +223,7 @@ namespace Host response.Success = true; } - catch (DakotaException e) + catch (GkvException e) { response.Message = e.Message; } @@ -264,30 +262,6 @@ namespace Host return finalpath; } - private string GetServerFromTenant(string tenant) - { -#if DEBUG - // return "localhost:3777"; -#endif - try - { - String url = String.Format(GETSERVER_URL, tenant); - using (WebClient client = new WebClient()) - { - //MessageBox.Show(hostAddress); - byte[] response = client.UploadValues(url, "POST", new NameValueCollection()); - - String server = System.Text.Encoding.ASCII.GetString(response); - - return server; - } - } - catch (Exception ex) - { - return null; - } - } - private void ClearResultFolder(string tenant, long[] oids) { var folder = new DirectoryInfo(Path.Combine(ResultFolderPath, tenant)); @@ -346,7 +320,6 @@ namespace Host } } - private void Sleep() => Thread.Sleep(5000); private void SendInvalidInputResponse() => SendErrorResponse(INVALID_INPUT); diff --git a/Host/Web.config b/Host/Web.config index daa6e26e4..856ea9b0a 100644 --- a/Host/Web.config +++ b/Host/Web.config @@ -240,6 +240,7 @@ + diff --git a/Service/ServiceContracts/IAccountingService.cs b/Service/ServiceContracts/IAccountingService.cs index b9bf9366a..2c76ebe15 100644 --- a/Service/ServiceContracts/IAccountingService.cs +++ b/Service/ServiceContracts/IAccountingService.cs @@ -171,6 +171,6 @@ namespace BeWo.Service.ServiceContracts [FaultContract(typeof(BeWoFault))] [OperationContract] - GkvServerGetIKResponseDC SendApp8GetIKRequest(GkvServerGetIKRequestDC req); + GkvAbrechnungGetIKResponseDC SendApp8GetIKRequest(GkvAbrechnungGetIKRequestDC req); } } \ No newline at end of file diff --git a/Service/ServiceImplementations/AccountingServiceImp.cs b/Service/ServiceImplementations/AccountingServiceImp.cs index f5636e35e..8cf61bfc5 100644 --- a/Service/ServiceImplementations/AccountingServiceImp.cs +++ b/Service/ServiceImplementations/AccountingServiceImp.cs @@ -26,6 +26,7 @@ using Newtonsoft.Json; using BS.Shared.DataContracts.GkvAbrechnung; using BS.Shared.Extensions; using BS.Shared.Exceptions; +using BS.Shared.AppSender; namespace BeWo.Service.ServiceImplementations { @@ -848,12 +849,10 @@ namespace BeWo.Service.ServiceImplementations response.Success = true; response.GkvAbrechnungDC = gkv_abrechnung_dc; - - return response; } catch (GkvException exc) { - response.Error = exc.Message; + response.Message = exc.Message; } catch (Exception e) { @@ -900,8 +899,6 @@ namespace BeWo.Service.ServiceImplementations { var response = new GkvAbrechnungSendResponseDC(); - response.Successful = false; - var oid = req.GkvAbrechnungOid; var entity = DAOFactory.GenericDAO.LoadByID(oid); @@ -937,7 +934,7 @@ namespace BeWo.Service.ServiceImplementations MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MergeWithEntity(app8_protokoll, protokoll); - response.Successful = app8_response.Success; + response.Success = app8_response.Success; } catch (GkvException de) { @@ -961,6 +958,39 @@ namespace BeWo.Service.ServiceImplementations return response; } + public GkvAbrechnungGetIKResponseDC SendApp8GetIKRequest(GkvAbrechnungGetIKRequestDC req) + { + try + { + var app8req = new GkvServerGetIKRequestDC + { + IKKrankenkasse = req.IKKrankenkasse, + Leistungserbringergruppe = req.Leistungserbringergruppe, + Abrechnungscode = DakotaUtils.GetAbrechnungscode(req.Leistungserbringergruppe), + Tarifkennzeichen = DakotaUtils.GetTarifkennzeichen(req.Leistungserbringergruppe) + }; + + var app8res = SendApp8Request(app8req); + + var res = new GkvAbrechnungGetIKResponseDC + { + BezDatenannahmestelle = app8res.BezDatenannahmestelle, + Gefunden = app8res.Gefunden, + IKDatenannahmestelle = app8res.IKDatenannahmestelle, + IKKostentrager = app8res.IKKostentrager, + IKKrankenkasse = app8res.IKKrankenkasse, + Message = app8res.Message, + Success = app8res.Success + }; + + return res; + } + catch (Exception e) + { + throw Utils.CreateBeWoFaultException(e); + } + } + private void CreateGkvTransferProtokoll(long oid, GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll) { try @@ -968,39 +998,13 @@ namespace BeWo.Service.ServiceImplementations var manager = new DakotaManager(); var mandatordc = new OperationsServiceImp().GetMandator(); - DakotaUtils.ValidateMandator(mandatordc); - - var orga = gkvAbrechnung.GetOrganisation(); - - DakotaUtils.ValidateOrganisation(orga); - - if (!DakotaValidator.IsOrganisationInformationValid(orga.IKDatenannahmestelle, orga.IKKostentrager, orga.IKKrankenkasse, orga.BezDatenannahmestelle)) - { - var res = SendApp8GetIKRequest(orga); - - if (!res.Success) - throw new GkvException(res.Message, "Interner Fehler"); - - if (!res.Gefunden) - throw new GkvException($"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; - orga.BezDatenannahmestelle = res.BezDatenannahmestelle; - - if (!DakotaValidator.IsOrganisationInformationValid(orga.IKDatenannahmestelle, orga.IKKostentrager, orga.IKKrankenkasse, orga.BezDatenannahmestelle)) - throw new GkvException($"Für die Organisation \"{orga.Name}\" konnten die hinterlegten IKs nicht verifiziert werden: \"{orga.BezDatenannahmestelle}\", \"{orga.IKDatenannahmestelle}\", \"{orga.IKKostentrager}\", \"{orga.IKKrankenkasse}\"", "Interner Fehler"); - - DAOFactory.GenericDAO.Update(orga); - - gkvAbrechnung = DAOFactory.GenericDAO.LoadByID(oid); - } + DakotaValidator.ValidateMandator(mandatordc); var gkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkvAbrechnung); var orgadc = gkvAbrechnungDC.Organisation; + DakotaValidator.ValidateOrganisation(orgadc); + var datenannahmestelle = orgadc.IKDatenannahmestelle; var (datenaustauschreferenz, transfernummer) = GetNextDatenaustauschreferenzTransfernummer(gkvAbrechnung, datenannahmestelle); var (dat_short, tra_short) = ClearDatenaustauschreferenzTransfernummer(datenaustauschreferenz, transfernummer); @@ -1019,7 +1023,7 @@ namespace BeWo.Service.ServiceImplementations var servicedc = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(service); var customerdc = MapperFactory.CustomerDC_Customer.MapToNewDC(customer); - DakotaUtils.ValidateCustomer(customerdc); + DakotaValidator.ValidateCustomer(customerdc); manager.Add(servicedc, orgadc, customerdc, mandatordc, dat_short, tra_short); } @@ -1060,7 +1064,7 @@ namespace BeWo.Service.ServiceImplementations protokoll.Dateiname = protokoll.Transfername; protokoll.AbsenderBezeichnung = "ownSoft GmbH"; - protokoll.EmpfangerBezeichnung = orga.BezDatenannahmestelle; + protokoll.EmpfangerBezeichnung = orgadc.BezDatenannahmestelle; } catch (GkvException de) { @@ -1162,13 +1166,13 @@ namespace BeWo.Service.ServiceImplementations } if (!response_app8.Success) - throw new DakotaException(response_app8.Message); + throw new GkvException(response_app8.Message); bool allAreUpToDate = true; for (int id = 0; id < updateables_len; id++) { var gkv_abrechnung = updateables[id]; - var result = response_app8.Result[id]; + var result = response_app8.ResultDC[id]; if (result is null) continue; @@ -1190,83 +1194,22 @@ namespace BeWo.Service.ServiceImplementations return allAreUpToDate; } - public GkvServerGetIKResponseDC SendApp8GetIKRequest(GkvServerGetIKRequestDC req) + + private Res SendApp8Request(Req request) where Req : GkvRequestDC where Res : GkvResponseDC { - try - { - req.Abrechnungscode = DakotaUtils.GetAbrechnungscode(req.Leistungserbringergruppe); - req.Tarifkennzeichen = DakotaUtils.GetTarifkennzeichen(req.Leistungserbringergruppe); - - return SendApp8Request(req); - } - catch (Exception e) - { - throw Utils.CreateBeWoFaultException(e); - } - } - - private GkvServerGetIKResponseDC SendApp8GetIKRequest(Organisation orga) - { - var gruppe = orga.Leistungserbringergruppe; - var abr = DakotaUtils.GetAbrechnungscode(gruppe); - var tarif = DakotaUtils.GetTarifkennzeichen(gruppe); - - var request = new GkvServerGetIKRequestDC - { - Abrechnungscode = abr, - IKKrankenkasse = orga.IKKrankenkasse, - Tarifkennzeichen = tarif - }; - - return SendApp8Request(request); - } - - private T2 SendApp8Request(T request) where T : GkvRequestDC where T2 : GkvResponseDC - { - string url = "https://app8.bewoplaner.de/service/GkvAbrechnungView.aspx"; - -#if DEBUG - url = "http://localhost:3777/Host/GkvAbrechnungView.aspx"; -#endif - var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser; if (user == null) { - throw new GkvException("User unbekannt", "KApp"); + throw new GkvException("User unbekannt", "KundenApp"); } request.Username = user.LoginName; request.Password = user.BCryptPassword; request.Tenant = MultitenancyOperationContextExt.Current.Tenant; - return JsonConvert.DeserializeObject(SendApp8Request(url, JsonConvert.SerializeObject(request))); + return GkvSender.SendApp8Request(request, request.Tenant); } - private string SendApp8Request(string url, string dataString) - { - string response_app8_str; - - try - { - url += "?tenant=" + MultitenancyOperationContextExt.Current.Tenant; - - using (WebClient client = new WebClient()) - { - client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); - - response_app8_str = client.UploadString(url, "POST", dataString); - } - } - catch (Exception e) - { - throw new GkvException(e.Message, "App8"); - } - - if (string.IsNullOrEmpty(response_app8_str)) - throw new GkvException("Leere Antwort", "App8"); - - return response_app8_str; - } - + #endregion } } \ No newline at end of file diff --git a/Shared/AppSender/AppRequestSender.cs b/Shared/AppSender/AppRequestSender.cs index 6c93e3e0d..5448b5dba 100644 --- a/Shared/AppSender/AppRequestSender.cs +++ b/Shared/AppSender/AppRequestSender.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using System.Net; using System.Text; @@ -11,6 +12,32 @@ namespace BS.Shared.AppSender { public static class AppRequestSender { + private static readonly string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0"; + + public static string GetServerFromTenant(string tenant) + { +#if DEBUG + // return "localhost:3777"; +#endif + try + { + String url = String.Format(GETSERVER_URL, tenant); + using (WebClient client = new WebClient()) + { + //MessageBox.Show(hostAddress); + byte[] response = client.UploadValues(url, "POST", new NameValueCollection()); + + String server = System.Text.Encoding.ASCII.GetString(response); + + return server; + } + } + catch (Exception ex) + { + return null; + } + } + public static Res Send(Req request, string url, string tenant) where Req : AppRequestDC where Res : AppResponseDC { request.Tenant = tenant; diff --git a/Shared/AppSender/GkvSender.cs b/Shared/AppSender/GkvSender.cs index e09c59361..f8da5d9bd 100644 --- a/Shared/AppSender/GkvSender.cs +++ b/Shared/AppSender/GkvSender.cs @@ -9,6 +9,8 @@ namespace BS.Shared.AppSender { public static class GkvSender { + private static readonly string GKVCLIENT_URL = "{0}/GkvAbrechnungClient.aspx"; + public static string SerializeResponse(Res response) where Res : AppResponseDC => JsonConvert.SerializeObject(response); public static Req DeserializeRequest(string str, Action sendInvalidInputResponse) where Req : AppRequestDC @@ -44,8 +46,6 @@ namespace BS.Shared.AppSender try { - var data = JsonConvert.SerializeObject(request); - app8_response = AppRequestSender.Send(request, url, tenant); } catch (Exception e) @@ -58,5 +58,36 @@ namespace BS.Shared.AppSender return app8_response; } + + public static Res SendKundenAppClientRequest(Req request, string tenant) where Req : GkvRequestDC where Res : GkvResponseDC + { + string server = AppRequestSender.GetServerFromTenant(tenant); + + if (string.IsNullOrEmpty(server)) + return null; + + var url = string.Format(GKVCLIENT_URL, $"https://{server}/service"); + +#if DEBUG + if (server.IndexOf("localhost") > 0) + url = string.Format(GKVCLIENT_URL, $"http://{server}/Host"); +#endif + + Res app8_response; + + try + { + app8_response = AppRequestSender.Send(request, url, tenant); + } + catch (Exception e) + { + throw new GkvException(e.Message, "KundenApp"); + } + + if (app8_response is null) + throw new GkvException("Leere Antwort", "KundenApp"); + + return app8_response; + } } } diff --git a/Shared/Core/DakotaValidator.cs b/Shared/Core/DakotaValidator.cs index 4675c1f23..b8fd0e33a 100644 --- a/Shared/Core/DakotaValidator.cs +++ b/Shared/Core/DakotaValidator.cs @@ -1,5 +1,6 @@ using BS.Shared.DataContracts; using BS.Shared.DataContracts.GkvAbrechnung; +using BS.Shared.Exceptions; using System; using System.Collections.Generic; using System.Linq; @@ -25,12 +26,59 @@ namespace BS.Shared.Core return null; } - public static bool IsMandatorValid(string ik_leistungserbringer) - => IsIKNumberValid(ik_leistungserbringer); + /// + /// Validiert in erster Phase den Mandator. + /// + public static void ValidateMandator(MandatorDC mandatordc) + { + if (mandatordc == null) + throw new GkvException("Mandator ist null"); + + if (!DakotaValidator.IsIKNumberValid(mandatordc.IKLeistungserbringer)) + throw new GkvException($"Die IK Nummer des Leistungserbringers \"{mandatordc.IKLeistungserbringer}\" ist ungültig."); + } + + /// + /// Validiert in zweiter Phase die Daten. Bei Fehler wird eine DakotaException geworfen. + /// + public static void ValidateCustomer(CustomerDC customerDC) + { + string error = null; + + if (customerDC == null) + error = "Customer ist null"; + else if (!IsVersichertennummerValid(customerDC.InsuranceNumber)) + error = $"Klient/in \"{customerDC.LastName}, {customerDC.FirstName}\" hat keine gültige Versichertennummer"; + else if (!IsVersichertenstatusValid(customerDC.VersichertenStatus)) + error = $"Klient/in \"{customerDC.LastName}, {customerDC.FirstName}\" hat keinen gültigen Versichertenstatus"; + + if (error != null) + throw new GkvException(error); + } + + public static void ValidateOrganisation(OrganisationDC orga) + { + string error = null; + + if (orga == null) + error = "Organisation ist null"; + else if (!IsLeistungserbringergruppeValid(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 (!IsIKNumberValid(orga.IKKrankenkasse)) + error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Krankenkasse Kennzeichen: \"{orga.IKKrankenkasse}\"."; + else if (!IsIKNumberValid(orga.IKKostentrager)) + error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Kostenträger Kennzeichen: \"{orga.IKKostentrager}\"."; + else if (!IsIKNumberValid(orga.IKDatenannahmestelle)) + error = $"Die Organisation \"{orga.Name}\" hat kein gültiges IK Datenannahmestelle Kennzeichen: \"{orga.IKDatenannahmestelle}\"."; + else if (!string.IsNullOrEmpty(orga.BezDatenannahmestelle)) + error = $"Die Organisation \"{orga.Name}\" hat keine gültige Bezeichnung Datenannahmestelle: \"{orga.BezDatenannahmestelle}\"."; + + if (error != null) + throw new GkvException(error); + } + public static bool IsOrganisationInformationValid(string ik_datenannahmestelle, string ik_kostentrager, string ik_krankenkasse, string bez_datenannahmestelle) => IsIKNumberValid(ik_datenannahmestelle, ik_kostentrager, ik_krankenkasse) && !string.IsNullOrEmpty(bez_datenannahmestelle); - public static bool IsCustomerValid(string insurance_number, string insurance_status) - => IsVersichertennummerValid(insurance_number) && IsVersichertenstatusValid(insurance_status); public static bool IsIKNumberValid(params string[] iks) => iks?.All(IsIKNumberValid) ?? false; @@ -44,7 +92,6 @@ namespace BS.Shared.Core return int.TryParse(iknummer, out int x); } - public static bool IsVersichertennummerValid(string nummer) { if (nummer == null) @@ -55,7 +102,6 @@ namespace BS.Shared.Core return true; } - public static bool IsVersichertenstatusValid(string status) { if (status == null) @@ -66,7 +112,6 @@ namespace BS.Shared.Core return true; } - public static bool IsLeistungserbringergruppeValid(string code) { if (code == null) diff --git a/Shared/DataContracts/AppRequestDC.cs b/Shared/DataContracts/AppRequestDC.cs index c49219567..823e84c31 100644 --- a/Shared/DataContracts/AppRequestDC.cs +++ b/Shared/DataContracts/AppRequestDC.cs @@ -13,13 +13,17 @@ namespace BS.Shared.DataContracts [DataContract] public abstract class AppRequestDC : IDataContract { - [DataMember] public string Tenant { get; set; } - [DataMember] public RequestType Type { get; set; } - - public AppRequestDC(RequestType type, string tenant) + public AppRequestDC(RequestType type) { Type = type; + } + + public AppRequestDC(RequestType type, string tenant) : this(type) + { Tenant = tenant; } + + [DataMember] public string Tenant { get; set; } + [DataMember] public RequestType Type { get; set; } } } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungCreateResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungCreateResponseDC.cs index f25fedec3..3a1f32af9 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungCreateResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungCreateResponseDC.cs @@ -10,6 +10,9 @@ namespace BS.Shared.DataContracts.GkvAbrechnung [DataContract] public class GkvAbrechnungCreateResponseDC : GkvResponseDC { + public GkvAbrechnungCreateResponseDC() + : base() { } + public GkvAbrechnungCreateResponseDC(bool success) : base(success) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungGetIKResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungGetIKResponseDC.cs index 438ec984a..ef3a3a35e 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungGetIKResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungGetIKResponseDC.cs @@ -10,6 +10,7 @@ namespace BS.Shared.DataContracts.GkvAbrechnung [DataContract] public class GkvAbrechnungGetIKResponseDC : GkvResponseDC { + public GkvAbrechnungGetIKResponseDC() : base() { } public GkvAbrechnungGetIKResponseDC(bool success) : base(success) { } public GkvAbrechnungGetIKResponseDC(bool success, string message) : base(success, message) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungSendResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungSendResponseDC.cs index a0f4f0ddc..64dc65061 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungSendResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvAbrechnungSendResponseDC.cs @@ -10,9 +10,12 @@ namespace BS.Shared.DataContracts.GkvAbrechnung [DataContract] public class GkvAbrechnungSendResponseDC : GkvResponseDC { + public GkvAbrechnungSendResponseDC() + : base() { } + public GkvAbrechnungSendResponseDC(bool success) : base(success) { } - + public GkvAbrechnungSendResponseDC(bool success, string message) : base(success, message) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvClientResultRequestDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvClientResultRequestDC.cs index af7119e0f..af6a16feb 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvClientResultRequestDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvClientResultRequestDC.cs @@ -9,10 +9,11 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvClientResultRequestDC : GkvRequestDC { - public GkvClientResultRequestDC(string tenant, string username, string password) - : base(RequestType.GkvClientResult, tenant, username, password) { } + public GkvClientResultRequestDC() + : base(RequestType.GkvClientResult) { } - [DataMember] public long Protokoll_Fehler_Oid; - [DataMember] public IList Protokoll_Folgefehler_Oid; + [DataMember] public string GkvSecretKey { get; set; } + [DataMember] public long Protokoll_Fehler_Oid { get; set; } + [DataMember] public IList Protokoll_Folgefehler_Oid { get; set; } } } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvRequestDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvRequestDC.cs index 73edbfc93..47d314fc9 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvRequestDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvRequestDC.cs @@ -7,16 +7,18 @@ using System.Threading.Tasks; namespace BS.Shared.DataContracts.GkvAbrechnung { - [DataContract] - public class GkvRequestDC : AppRequestDC - { - public GkvRequestDC(RequestType type, string tenant, string username, string password) : base(type, tenant) - { - Username = username; - Password = password; - } + [DataContract] + public class GkvRequestDC : AppRequestDC + { + public GkvRequestDC(RequestType type) : base(type) { } - [DataMember] public string Username { get; set; } - [DataMember] public string Password { get; set; } - } + public GkvRequestDC(RequestType type, string tenant, string username, string password) : base(type, tenant) + { + Username = username; + Password = password; + } + + [DataMember] public string Username { get; set; } + [DataMember] public string Password { get; set; } + } } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvResponseDC.cs index d92e065e8..123384dc0 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvResponseDC.cs @@ -10,6 +10,7 @@ namespace BS.Shared.DataContracts.GkvAbrechnung [DataContract] public class GkvResponseDC : AppResponseDC { + public GkvResponseDC() : base(false) { } public GkvResponseDC(bool success) : base(success) { } public GkvResponseDC(bool success, string message) : base(success, message) { } } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKRequestDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKRequestDC.cs index cc2df0fcf..5401be61a 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKRequestDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKRequestDC.cs @@ -9,6 +9,9 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvServerGetIKRequestDC : GkvRequestDC { + public GkvServerGetIKRequestDC() + : base(RequestType.GkvServerGetIKNumber) { } + public GkvServerGetIKRequestDC(string tenant, string username, string password) : base(RequestType.GkvServerGetIKNumber, tenant, username, password) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKResponseDC.cs index f88e848ed..d48c7c7ab 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvServerGetIKResponseDC.cs @@ -9,6 +9,7 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvServerGetIKResponseDC : GkvResponseDC { + public GkvServerGetIKResponseDC() : base() { } public GkvServerGetIKResponseDC(bool success) : base(success) { } public GkvServerGetIKResponseDC(bool success, string message) : base(success, message) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvServerGetStatusRequestDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvServerGetStatusRequestDC.cs index a502f0bd6..7f904d9b3 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvServerGetStatusRequestDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvServerGetStatusRequestDC.cs @@ -9,6 +9,9 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvServerGetStatusRequestDC : GkvRequestDC { + public GkvServerGetStatusRequestDC() + : base(RequestType.GkvServerGetStatus) { } + public GkvServerGetStatusRequestDC(string tenant, string username, string password) : base(RequestType.GkvServerGetStatus, tenant, username, password) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewRequestDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewRequestDC.cs index 956fcd067..e254db972 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewRequestDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewRequestDC.cs @@ -9,6 +9,9 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvServerSendNewRequestDC : GkvRequestDC { + public GkvServerSendNewRequestDC() + : base(RequestType.GkvServerSendNew) { } + public GkvServerSendNewRequestDC(string tenant, string username, string password) : base(RequestType.GkvServerSendNew, tenant, username, password) { } diff --git a/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewResponseDC.cs b/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewResponseDC.cs index 371628435..bc26c4ef3 100644 --- a/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewResponseDC.cs +++ b/Shared/DataContracts/GkvAbrechnung/GkvServerSendNewResponseDC.cs @@ -9,6 +9,9 @@ namespace BS.Shared.DataContracts.GkvAbrechnung { public class GkvServerSendNewResponseDC : GkvResponseDC { + public GkvServerSendNewResponseDC() + : base() { } + public GkvServerSendNewResponseDC(bool success) : base(success) { }