Konflikte gelöst.

This commit is contained in:
2025-01-17 16:32:01 +01:00
892 changed files with 150017 additions and 183923 deletions

View File

@@ -27,12 +27,15 @@ using BS.Shared.DataContracts.GkvAbrechnung;
using BS.Shared.Extensions;
using BS.Shared.Exceptions;
using BS.Shared.AppSender;
using BeWo.Data.Security;
namespace BeWo.Service.ServiceImplementations
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class AccountingServiceImp : IAccountingService
{
public string Tenant => MultitenancyOperationContextExt.Current?.Tenant;
public void DeactivateInvoiceBases(List<InvoiceBaseDC> invoices)
{
try
@@ -666,18 +669,18 @@ namespace BeWo.Service.ServiceImplementations
}
}
public List<long> UpdateServiceInvoices(List<ServiceInvoiceDC> invoices)
{
try
{
var acc = PluginLoader.FindClass<AccountingService>();
return acc.UpdateServiceInvoices(invoices);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> UpdateServiceInvoices(List<ServiceInvoiceDC> invoices)
{
try
{
var acc = PluginLoader.FindClass<AccountingService>();
return acc.UpdateServiceInvoices(invoices);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public void UpdateSettlementInvoice(List<Settlement2DC> invoices)
{
@@ -817,6 +820,10 @@ namespace BeWo.Service.ServiceImplementations
try
{
var invoice_bases = DAOFactory.GenericDAO.LoadByIDs<InvoiceBase>(request.SelectedInvoiceBases);
ValidatorExtended.ValidateGkvAbrechnung(request.GkvAbrechnungDC, invoice_bases);
var gkv_abrechnung = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewEntity(request.GkvAbrechnungDC);
if (gkv_abrechnung.AbrechnungsZeitraumEnde.Value.Hour == 0)
@@ -824,7 +831,7 @@ namespace BeWo.Service.ServiceImplementations
gkv_abrechnung.AbrechnungsZeitraumEnde = gkv_abrechnung.AbrechnungsZeitraumEnde.Value.Date.AddDays(1).AddMilliseconds(-1);
}
var orga = gkv_abrechnung.GetOrganisation();
var orga = gkv_abrechnung.Organisation;
gkv_abrechnung.Verfahrensstufe = orga.Verfahrensstufe;
@@ -832,9 +839,6 @@ namespace BeWo.Service.ServiceImplementations
foreach (var invoicebase_oid in request.SelectedInvoiceBases)
{
var service = DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoicebase_oid);
var invoicebase = DAOFactory.GenericDAO.GetByID<InvoiceBase>(invoicebase_oid);
var invoicebase_dc = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDC(invoicebase);
foreach (var peroid in service.ServiceInvoicePeriodList)
{
@@ -859,10 +863,16 @@ namespace BeWo.Service.ServiceImplementations
}
catch (GkvException exc)
{
MailUtils.SendGkvModuleErrorMail("CreateNewGkvAbrechnung", exc, Tenant);
if (exc.Title.IsNotNullOrWhiteSpace())
response.TitleMessage = exc.Title;
response.Message = exc.Message;
}
catch (Exception e)
{
MailUtils.SendGkvModuleErrorMail("CreateNewGkvAbrechnung", e, Tenant);
throw Utils.CreateBeWoFaultException(e);
}
@@ -918,24 +928,26 @@ namespace BeWo.Service.ServiceImplementations
return response;
}
var protokoll = new GkvTransferProtokoll
var protokoll = CreateGkvTransferProtokoll(entity, out var error);
if (error is object)
{
ErstelltAm = DateTime.Now,
GkvAbrechnungOid = entity.Oid.Value
};
MailUtils.SendGkvModuleErrorMail("SendNewGkvAbrechnung - CreateGkvTransferProtokoll", error, Tenant);
response.TitleMessage = "Protokoll Erstellung";
response.Message = error;
return response;
}
if (entity.GkvTransferProtokolle is null)
entity.GkvTransferProtokolle = new List<GkvTransferProtokoll>();
entity.GkvTransferProtokolle.Add(protokoll);
// Protokoll braucht Oid
DAOFactory.GenericDAO.Update(entity);
try
{
CreateGkvTransferProtokoll(oid, entity, protokoll);
if (entity.GkvTransferProtokolle is null)
entity.GkvTransferProtokolle = new List<GkvTransferProtokoll>();
entity.GkvTransferProtokolle.Add(protokoll);
// Protokoll braucht Oid
DAOFactory.GenericDAO.Update(entity);
var app8_response = SendApp8SendNewRequest(protokoll);
var app8_protokoll = app8_response.GkvTransferProtokollDC;
@@ -992,6 +1004,22 @@ namespace BeWo.Service.ServiceImplementations
Success = app8res.Success
};
if (res.Gefunden)
{
var orgas = DAOFactory.SearchDAO.GetAllOrganisationByIKKrankenkasse(req.IKKrankenkasse);
if (req.OrganisationOid is long oid)
{
orgas.RemoveAll(x => x.Oid == oid);
}
if (orgas.Any())
{
res.BereitsEnthalten = true;
res.BereitsEnthaltenBei = orgas.Select(x => x.Name).ToList();
}
}
return res;
}
catch (Exception e)
@@ -1000,26 +1028,50 @@ namespace BeWo.Service.ServiceImplementations
}
}
private void CreateGkvTransferProtokoll(long oid, GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll)
private GkvTransferProtokoll CreateGkvTransferProtokoll(GkvAbrechnung gkvAbrechnung, out string error)
{
var protokoll = new GkvTransferProtokoll
{
ErstelltAm = DateTime.Now,
GkvAbrechnungOid = gkvAbrechnung.Oid.Value
};
error = null;
try
{
ValidatorExtended.ValidateGkvAbrechnung(gkvAbrechnung, gkvAbrechnung.InvoiceBases);
var manager = new DakotaManager();
var mandatordc = new OperationsServiceImp().GetMandator();
DakotaValidator.ValidateMandator(mandatordc);
Validator.ValidateMandator(mandatordc);
var gkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkvAbrechnung);
var orgadc = gkvAbrechnungDC.Organisation;
DakotaValidator.ValidateOrganisation(orgadc);
Validator.ValidateOrganisation(orgadc);
var datenannahmestelle = orgadc.IKDatenannahmestelle;
var (datenaustauschreferenz, transfernummer) = GetNextDatenaustauschreferenzTransfernummer(gkvAbrechnung, datenannahmestelle);
var (dat_short, tra_short) = ClearDatenaustauschreferenzTransfernummer(datenaustauschreferenz, transfernummer);
protokoll.Datenaustauschreferenz = datenaustauschreferenz;
protokoll.Transfernummer = transfernummer;
var first_cost = gkvAbrechnung.InvoiceBases.First().CostBearer2SupportConcept.SupportConcept.Customer;
var plugin = PluginLoader.FindClass<AccountingService>();
var addressInfo = plugin.GetAddressInformation(first_cost.Oid);
foreach (var invoicebase in gkvAbrechnung.InvoiceBases)
{
var customer = invoicebase.CostBearer2SupportConcept.SupportConcept.Customer;
var addressInfo2 = plugin.GetAddressInformation(customer.Oid);
if (addressInfo.IKLeistungserbringer != addressInfo2.IKLeistungserbringer)
{
throw new GkvException($"Klient '{first_cost.Person.LastNameFirstName}' ({addressInfo.IKLeistungserbringer}) und '{customer.Person.LastNameFirstName}' ({addressInfo2.IKLeistungserbringer}) verweisen auf unterschiedliche Leistungserbringer.");
}
}
foreach (var invoicebase in gkvAbrechnung.InvoiceBases)
{
@@ -1032,16 +1084,18 @@ namespace BeWo.Service.ServiceImplementations
var servicedc = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(service);
var customerdc = MapperFactory.CustomerDC_Customer.MapToNewDC(customer);
DakotaValidator.ValidateCustomer(customerdc);
Validator.ValidateCustomer(customerdc);
manager.Add(servicedc, orgadc, customerdc, mandatordc, dat_short, tra_short);
manager.Add(servicedc, orgadc, customerdc, addressInfo, dat_short, tra_short);
}
manager.Apply();
if (manager.DakotaFileDict.Count != 1 || manager.DakotaFileDict.First().Value.GetKostenträgerCount() != 1)
{
throw new GkvException("Unerwartete Anzahl an Dakota Files berechnet.");
var msg = "Unerwartete Anzahl an Dakota Files berechnet.";
throw new GkvException(msg);
}
var file_from_manager = manager.DakotaFileDict.First().Value;
@@ -1049,15 +1103,26 @@ namespace BeWo.Service.ServiceImplementations
var nutzdatendatei = file_from_manager.GetNutzdatendatei();
// https://dev.mysql.com/doc/refman/8.3/en/string-type-syntax.html
// A TEXT column with a maximum length of 65,535 (2^16 1) characters.
// The effective maximum length is less if the value contains multibyte
// characters. Each TEXT value is stored using a 2-byte length prefix
// that indicates the number of bytes in the value.
if (nutzdatendatei.Length > 65535)
// A TEXT column with a maximum length of 16,777,215 (224 1) characters.
// The effective maximum length is less if the value contains multibyte characters.
// Each MEDIUMTEXT value is stored using a 3-byte length prefix that indicates the number of bytes in the value.
//
// Type | Maximum length
// -----------+-------------------------------------
// TINYTEXT | 255(2^81) bytes
// TEXT | 65,535(2^161) bytes = 64 KiB
// MEDIUMTEXT | 16,777,215(2^241) bytes = 16 MiB
// LONGTEXT | 4,294,967,295(2^321) bytes = 4 GiB
if (nutzdatendatei.Length > 16777215)
{
throw new GkvException($"nutzdatendatei - Länger als 65535: {nutzdatendatei.Length}");
var msg = $"nutzdatendatei - Länger als 16777215: {nutzdatendatei.Length}";
throw new GkvException(msg);
}
protokoll.Datenaustauschreferenz = datenaustauschreferenz;
protokoll.Transfernummer = transfernummer;
protokoll.IKDatenannahmestelle = file_from_manager.GetIKDatenannahmestelle();
protokoll.IKKostentrager = file_from_manager.GetIKKostenträger();
protokoll.IKLeistungserbringer = file_from_manager.GetIKLeistungserbringer();
@@ -1074,18 +1139,19 @@ namespace BeWo.Service.ServiceImplementations
protokoll.AbsenderBezeichnung = "ownSoft GmbH";
protokoll.EmpfangerBezeichnung = orgadc.BezDatenannahmestelle;
return protokoll;
}
catch (GkvException de)
{
if (string.IsNullOrEmpty(de.Title))
de.Title = "Protokoll Erstellung";
throw de;
error = de.ToString();
}
catch (Exception e)
{
throw new GkvException(e.Message, "Erstellung");
error = e.ToString();
}
return null;
}
private Tuple<int, int> GetNextDatenaustauschreferenzTransfernummer(GkvAbrechnung gkvAbrechnung, string datenannahmestelle)
@@ -1105,7 +1171,7 @@ namespace BeWo.Service.ServiceImplementations
}
else
{
throw new ArgumentException("Versucht Transfernummer zu laden, invalid state", nameof(state));
throw new ArgumentException($"Versucht Transfernummer zu laden, invalid state: {state}", nameof(state));
}
return new Tuple<int, int>(datenaustauschref, transfernummer);
@@ -1171,14 +1237,14 @@ namespace BeWo.Service.ServiceImplementations
}
catch (Exception e)
{
throw e;
MailUtils.SendGkvModuleErrorMail("GkvServerGetStatusRequest Error", e, Tenant);
return true;
}
if (!response_app8.Success)
throw new GkvException("Success false - " + response_app8.Message);
if (response_app8.Results is null)
throw new GkvException("Result null - " + response_app8.Message);
@@ -1223,7 +1289,7 @@ namespace BeWo.Service.ServiceImplementations
protokolls.Add(protokoll);
}
if(protokolls.Any())
if (protokolls.Any())
DAOFactory.GenericDAO.Update(protokolls);
var follows = results.Where(x => x.ResultType == GkvTransferResultType.FailFollowUp);
@@ -1261,14 +1327,14 @@ namespace BeWo.Service.ServiceImplementations
request.Password = user.BCryptPassword;
request.Tenant = MultitenancyOperationContextExt.Current.Tenant;
if(request is GkvServerSendNewRequestDC send_new_req)
if (request is GkvServerSendNewRequestDC send_new_req)
{
send_new_req.ApplicationUserOid = user.Oid.Value;
}
return GkvSender.SendApp8Request<Req, Res>(request, request.Tenant);
}
#endregion
}
}

View File

@@ -859,7 +859,8 @@ namespace BeWo.Service.ServiceImplementations
{
IList<Organisation> list = DAOFactory.GenericDAO.GetAllActiveAndArchived<Organisation>();
list = list.Where(x => DakotaValidator.IsOrganisationInformationValid(x.IKDatenannahmestelle, x.IKKostentrager, x.IKKrankenkasse, x.BezDatenannahmestelle)).ToList();
list = list.Where(x => !x.GkvAusblenden &&
Validator.IsOrganisationInformationValid(x.IKDatenannahmestelle, x.IKKostentrager, x.IKKrankenkasse, x.BezDatenannahmestelle)).ToList();
return CreateCompactOrganisations(list);
}

View File

@@ -122,7 +122,7 @@ namespace BeWo.Service.ServiceImplementations
}
}
return Utils.SendMail(senderName, senderEMail, subject, body, null);
return Utils.SendMail(subject, body, null, senderName, senderEMail);
}
private MailDC CreateMailDC(Mail2Receiver m2r)

View File

@@ -2505,6 +2505,22 @@ namespace BeWo.Service.ServiceImplementations
//pServiceRecordGroup.RoundedDuration = (decimal)originalEnde.Value.Subtract(originalStart.Value).TotalMinutes;
}
}
//Bug korrigieren, dass sich die Stunden nicht ändern, wenn in Start Sekunde > 0 und Stunde > 0 eingetragen ist, was eigentlich nicht sein darf. War aber bei einem Kunden HSH Netzwerk bei zwei Usern
if (srOrg.Start.HasValue && srOrg.Start.Value.Hour > 0 && srOrg.Start.Value.Second > 0)
{
var minuten = srDc.RoundedDuration;
if (srDc.DurationInStunden.HasValue && srDc.DurationInStunden.Value == ZeiterfassungsDauer.Stunden)
{
minuten *= 60;
}
if (srOrg.RoundedDuration == minuten) // Die Dauer wurde nicht geändert, also setze Start auf 00:01
{
srDc.Start = srDc.Start.Value.Date.AddSeconds(1);
srDc.End = srDc.Start.Value.AddMinutes((double)minuten);
}
}
}
}
@@ -6200,12 +6216,11 @@ namespace BeWo.Service.ServiceImplementations
}
}
// TODO: implementieren!
public void DeleteAppointmentsInInterval(bool pHasRightToSeeAllEmployeeAppointments, long pEmployeeOid, DateTime pIntervalEnd, List<long> pSelectedEmployees, List<long> pSelectedCustomers, List<long> pSelectedResources, bool pEmployeesOnly, bool pCustomersOnly, bool pResourcesOnly, bool pPrivateAppointmentsOnly, bool pOnlyMyAppointments, Dictionary<UserRightType, bool> pUserRights)
{
try
{
var appointments2Delete = DAOFactory.SearchDAO.LoadFilteredAppointments(pHasRightToSeeAllEmployeeAppointments, pEmployeeOid, new DateTime(1, 1, 1), pIntervalEnd, pSelectedEmployees, pSelectedCustomers, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, true);
var appointments2Delete = DAOFactory.SearchDAO.LoadFilteredAppointments(pHasRightToSeeAllEmployeeAppointments, pEmployeeOid, new DateTime(1, 1, 1), pIntervalEnd, pSelectedEmployees, pSelectedCustomers, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, true, false);
DAOFactory.GenericDAO.Delete(appointments2Delete);
}
catch (Exception e)
@@ -6257,9 +6272,9 @@ namespace BeWo.Service.ServiceImplementations
public string GetMessageFromServerForDeletingAppointments(bool pHasRightToSeeAllEmployeeAppointments, long pEmployeeOid, DateTime pIntervalEnd, List<long> pSelectedEmployees, List<long> pSelectedCustomers, List<long> pSelectedResources, bool pEmployeesOnly, bool pCustomersOnly, bool pResourcesOnly, bool pPrivateAppointmentsOnly, bool pOnlyMyAppointments, Dictionary<UserRightType, bool> pUserRights)
{
var appointments2Delete = DAOFactory.SearchDAO.LoadFilteredAppointments(pHasRightToSeeAllEmployeeAppointments, pEmployeeOid, new DateTime(1, 1, 1), pIntervalEnd, pSelectedEmployees, pSelectedCustomers, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, true);
var appointments2Delete = DAOFactory.SearchDAO.LoadFilteredAppointments(pHasRightToSeeAllEmployeeAppointments, pEmployeeOid, new DateTime(1, 1, 1), pIntervalEnd, pSelectedEmployees, pSelectedCustomers, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, true, false);
var actualTextMessage = $"Achtung!&#x0a;&#x0a;Das Löschen von {appointments2Delete.Count} {(appointments2Delete.Count == 1 ? "Termin" : "Terminen")} bis zum {pIntervalEnd.ToShortDateString()} kann nicht rückgängig gemacht werden!&#x0a;";
var actualTextMessage = $"Achtung!&#x0a;&#x0a;Es werden ALLE Termine ALLER Klienten bis zum angegebenden Datum gelöscht.&#x0a;Das Löschen von {appointments2Delete.Count} {(appointments2Delete.Count == 1 ? "Termin" : "Terminen")} bis zum {pIntervalEnd.ToShortDateString()} kann nicht rückgängig gemacht werden!&#x0a;";
return $"<TextBlock xmlns =\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" Grid.Row=\"0\" TextAlignment=\"Center\" FontWeight=\"Bold\" TextWrapping=\"Wrap\" Background=\"Transparent\" FontSize=\"14\" Margin=\"3\" Foreground=\"Red\" HorizontalAlignment=\"Center\" Text=\"{actualTextMessage}\"/>";
}
@@ -7726,7 +7741,9 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetVorlagentabelleDCs();
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetVorlagentabelleDCs();
}
catch (Exception ex)
{
@@ -7739,18 +7756,35 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.InsertTemplate(dc);
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.InsertTemplate(dc);
}
catch (Exception ex)
{
throw Utils.CreateBeWoFaultException(ex);
}
}
public List<PlatzhalterDC> GetPlatzhalterForTemplate(VorlagentabelleDC vt)
{
try
{
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetPlatzhalterForTemplate(vt);
}
catch (Exception ex)
{
throw Utils.CreateBeWoFaultException(ex);
}
}
public List<PlatzhalterDC> GetPlatzhalterForCustomer()
{
try
{
return VorlagenManager.GetPlatzhalterForCustomer();
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetPlatzhalterForCustomer();
}
catch (Exception ex)
{
@@ -7761,7 +7795,8 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetPlatzhalterForSupportConcept();
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetPlatzhalterForSupportConcept();
}
catch (Exception ex)
{
@@ -7772,7 +7807,8 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetPlatzhalterForEmployee();
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetPlatzhalterForEmployee();
}
catch (Exception ex)
{
@@ -7783,7 +7819,8 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetFolderById(oid);
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetFolderById(oid);
}
catch (Exception ex)
{
@@ -7794,7 +7831,8 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetVorlagentabelleById(oid);
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetVorlagentabelleById(oid);
}
catch (Exception ex)
{
@@ -7805,7 +7843,21 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.GetDokumentvorlagenInFolder(folderOid);
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetDokumentvorlagenInFolder(folderOid);
}
catch (Exception ex)
{
throw Utils.CreateBeWoFaultException(ex);
}
}
public List<DokumentvorlageDC> GetDokumentvorlagenForType(TableID objecTid)
{
try
{
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.GetDokumentvorlagenForType(objecTid);
}
catch (Exception ex)
{
@@ -7830,7 +7882,9 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
VorlagenManager.DeleteTemplates(vorlagen);
var vm = PluginLoader.FindClass<VorlagenManager>();
vm.DeleteTemplates(vorlagen);
}
catch (Exception e)
{
@@ -7854,7 +7908,8 @@ namespace BeWo.Service.ServiceImplementations
{
try
{
return VorlagenManager.ReplacePlaceholdersInTemplate(template, objectOid, tableOid);
var vm = PluginLoader.FindClass<VorlagenManager>();
return vm.ReplacePlaceholdersInTemplate(template, objectOid, tableOid);
}
catch (Exception e)
{