Files
BeWoPlaner/Service/ServiceImplementations/AccountingServiceImp.cs

1309 lines
38 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using BeWo.Data;
using BeWo.Service.Plugins;
using BS.Shared.DataContracts.Compact;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceContracts;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using Utils = BeWo.Service.Core.Utils;
using BeWo.Service.Invoicing;
using Dakota.Logic;
using Dakota;
using Dakota.Models;
using System.Net;
using System.Collections.Specialized;
using Newtonsoft.Json;
using BS.Shared.DataContracts.GkvAbrechnung;
using BS.Shared.Extensions;
using BS.Shared.Exceptions;
using BS.Shared.AppSender;
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
{
var s = PluginLoader.FindClass<AccountingService>();
s.DeactivateInvoiceBases(invoices);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public void StorniereInvoiceBases(List<InvoiceBaseDC> invoices)
{
try
{
var s = PluginLoader.FindClass<AccountingService>();
s.StorniereInvoiceBases(invoices);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public void DeactivateServiceInvoices(List<ServiceInvoiceDC> invoices)
{
try
{
var s = PluginLoader.FindClass<AccountingService>();
s.DeactivateServiceInvoices(invoices);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public void DeactivateSettlementInvoice(List<Settlement2DC> invoices)
{
try
{
ServiceLogic.SetActivationType<SettlementInvoice>(invoices.ToDictionary(i => i.SettlementIvoiceOid.Value, i => i.SettlementInvoiceVersion.Value), ActivationTypeId.Deleted);
ServiceLogic.SetActivationType<InvoiceBase>(invoices.ToDictionary(i => i.InvoiceBaseOid.Value, i => i.InvoiceBaseVersion.Value), ActivationTypeId.Deleted);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<ServiceInvoiceDC> GenerateInitialServiceInvoices(
long costBearerOid,
long? supportConceptOid,
DateTimeSpan invoicePeriod)
{
try
{
var acc = PluginLoader.FindClass<AccountingService>();
return acc.GenerateInitialServiceInvoices(costBearerOid, supportConceptOid, invoicePeriod);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetAllActiveInvoiceBases()
{
try
{
return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive<InvoiceBase>());
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetInvoiceBases(DateTime? startDate, DateTime? endDate)
{
try
{
var s = PluginLoader.FindClass<AccountingService>();
return s.GetInvoiceBases(startDate, endDate);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetInvoiceBases2(DateTime? startDate, DateTime? endDate, bool filterByInvoiceDate)
{
try
{
var s = PluginLoader.FindClass<AccountingService>();
return s.GetInvoiceBases(startDate, endDate, filterByInvoiceDate);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetInvoiceBasesForCostBearerAndId(DateTime? startDate, DateTime? endDate, long costBearerOid, String invoiceId)
{
try
{
var s = PluginLoader.FindClass<AccountingService>();
return s.GetInvoiceBases(startDate, endDate, costBearerOid, invoiceId);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetInvoiceBasesForCostBearerAndIdAndIsUsed(DateTime? startDate, DateTime? endDate, long costBearerOid, String invoiceId)
{
try
{
var gkv_abrechnungen = DAOFactory.GenericDAO.GetAllActive<GkvAbrechnung>();
var s = PluginLoader.FindClass<AccountingService>();
var rtn = s.GetInvoiceBases(startDate, endDate, costBearerOid, invoiceId);
HashSet<long> invoices = new HashSet<long>();
foreach (var gkv_abrechnung in gkv_abrechnungen)
{
foreach (var invoice in gkv_abrechnung.InvoiceBases)
{
invoices.Add(invoice.Oid.Value);
}
}
foreach (var invoice in rtn)
{
invoice.IsAlreadyInActiveGkvAbrechnung = invoices.Contains(invoice.InvoiceBaseOid.Value);
}
return rtn;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetGeneralInvoiceBasesForCustomer(long customerOid)
{
try
{
return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByCustomerOid(InvoiceType.General, customerOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetGeneralInvoiceBasesForOrganisation(long organisationOid)
{
try
{
return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByOrganisationOid(InvoiceType.General, organisationOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetGeneralInvoiceBasesForPerson(long personOid)
{
try
{
return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByPersonOid(InvoiceType.General, personOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceBaseDC> GetInvoiceBasesForSupportConcept(InvoiceType type, long supportConceptOid)
{
try
{
return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByTypeAndSupportConceptOid(type, supportConceptOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public ServiceInvoiceDC GetServiceInvoiceByInvoiceBaseOid(long invoiceBaseOid)
{
try
{
var dc = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoiceBaseOid));
SortServiceInvoicePeriods(dc);
return dc;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<ServiceInvoiceDC> GetServiceInvoices(long costBearerOid, long? supportConceptOid, DateTimeSpan period)
{
try
{
List<ServiceInvoice> entities = DAOFactory.SearchDAO.GetServiceInvoices(costBearerOid, supportConceptOid, period);
entities.Sort((x, y) =>
{
if (y.InvoiceBase.InvoiceDate.Value.Date.Equals(x.InvoiceBase.InvoiceDate.Value.Date))
{
return y.InvoiceBase.InvoiceNumber.CompareTo(x.InvoiceBase.InvoiceNumber);
}
return y.InvoiceBase.InvoiceDate.Value.Date.CompareTo(x.InvoiceBase.InvoiceDate.Value.Date);
});
var dcList = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDCs(entities);
foreach (var serviceInvoice in dcList)
{
SortServiceInvoicePeriods(serviceInvoice);
}
return dcList;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
private void SortServiceInvoicePeriods(ServiceInvoiceDC serviceInvoice)
{
if (serviceInvoice.ServiceInvoicePeriods != null)
{
serviceInvoice.ServiceInvoicePeriods.Sort((x, y) =>
{
if (x.Customer != null && y.Customer != null)
return x.Customer.ToString().CompareTo(y.Customer.ToString());
else if (x.Start != null && y.Start != null)
{
x.Start.Value.CompareTo(y.Start.Value);
}
return 0;
});
}
}
public Settlement2DC GetSettlementByInvoiceBaseOid(long invoiceBaseOid)
{
try
{
return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDC(DAOFactory.SearchDAO.GetSettlementInvoiceByInvoiceBaseOid(invoiceBaseOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<Settlement2DC> GetSettlementInvoicesForCostBearerAndPeriod(long costBearerOid, DateTime periodStart, DateTime periodEnd)
{
try
{
return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDCs(DAOFactory.SearchDAO.GetSettlementInvoicesForCostBearerAndPeriod(costBearerOid, periodStart, periodEnd));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<Settlement2DC> GetSettlementInvoicesForSupportConcept(long supportConceptOid)
{
try
{
return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDCs(DAOFactory.SearchDAO.GetSettlementInvoiceBySupportConceptOid(supportConceptOid));
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> InsertNewInvoiceBases(List<InvoiceBaseDC> invoices)
{
try
{
if (invoices != null && LoggedInUserOperationContextExt.Current != null &&
LoggedInUserOperationContextExt.Current.User != null)
{
var loggedInUser = LoggedInUserOperationContextExt.Current.User;
foreach (var ib in invoices)
{
ib.SenderContactInformations = new List<ContactDC>();
foreach (var contact in loggedInUser.Employee.Person.Contacts)
{
var newContact = new ContactDC();
newContact.ContactType = contact.Type;
newContact.ContactValue = contact.Value;
ib.SenderContactInformations.Add(newContact);
}
}
}
var newInvoices = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewEntities(invoices);
int count = 0;
var inc = PluginLoader.FindClass<InvoiceNumberGenerator>();
foreach (var ib in newInvoices)
{
if (ib.Type == InvoiceType.General)
{
foreach (var item in ib.InvoiceItems)
{
item.AmountTotal = Math.Round(item.AmountTotal ?? 0, 2, MidpointRounding.AwayFromZero);
}
}
var nextNumber = inc.GetNextInvoiceNumber(count, ib);
if (!String.IsNullOrEmpty(nextNumber))
{
if (!String.IsNullOrEmpty(ib.InvoiceNumber)) // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben.
{
if (ib.InvoiceNumber == nextNumber)
//Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen
{
count++;
}
}
else
{
ib.InvoiceNumber = nextNumber;
count++;
}
}
}
var factory = PluginLoader.FindClass<InvoiceFactory>();
if (factory != null)
{
foreach (var ib in newInvoices)
{
if (ib.Type == InvoiceType.CustomerEquity)
{
var creator = factory.CreateEquityInvoiceCreator(ib);
creator.InitEquityInvoice(ib);
}
else if (ib.Type == InvoiceType.General)
{
var creator = factory.CreateGeneralInvoiceCreator(ib);
creator.InitInvoice(ib);
}
}
}
DAOFactory.GenericDAO.Insert(newInvoices);
inc.IncreaseInvoiceNumber(count, newInvoices);
return newInvoices.Select(i => i.Oid.Value).ToList();
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> InsertNewServiceInvoices(List<ServiceInvoiceDC> invoices)
{
try
{
//Prüfe Flags
var neueRechnungen = new List<ServiceInvoiceDC>();
var diffRechnungen = invoices.Where(i => i.InvoiceBase.DiffErstellen).ToList();
//Bei neuer Rechung prüfen, ob eine Diff Rechnung vorher generiert wurde.
foreach (var item in invoices.Where(i => i.InvoiceBase.NeuErstellen))
{
if (item.OriginalZurDifferenz != null)
{
neueRechnungen.Add(item.OriginalZurDifferenz);
}
else
{
neueRechnungen.Add(item);
}
}
var newInvoices = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewEntities(neueRechnungen);
newInvoices.AddRange(MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewEntities(diffRechnungen));
if (newInvoices.Count > 0)
{
int count = 0;
var inc = PluginLoader.FindClass<InvoiceNumberGenerator>();
foreach (var i in newInvoices)
{
var nextNumber = inc.GetNextInvoiceNumber(count, i.InvoiceBase);
if (!String.IsNullOrEmpty(nextNumber))
{
//if (!String.IsNullOrEmpty(i.InvoiceBase.InvoiceNumber) && newInvoices.Count == 1)
// // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben.
//{
// if (i.InvoiceBase.InvoiceNumber == nextNumber || newInvoices.Count > 1)
// //Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen
// {
// count++;
// }
//}
//else
//{
i.InvoiceBase.InvoiceNumber = nextNumber;
count++;
//}
}
}
DAOFactory.GenericDAO.Insert(newInvoices);
inc.IncreaseInvoiceNumberForServiceInvoices(count, newInvoices);
}
return newInvoices.Select(i => i.Oid.Value).ToList();
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> InsertNewSettlementInvoice(List<Settlement2DC> invoices)
{
try
{
var newInvoices = MapperFactory.SettlementDC_SettlementInvoice.MapToNewEntities(invoices);
int count = 0;
var inc = PluginLoader.FindClass<InvoiceNumberGenerator>();
foreach (var i in newInvoices)
{
var nextNumber = inc.GetNextInvoiceNumber(count, i.InvoiceBase);
if (!String.IsNullOrEmpty(nextNumber))
{
if (!String.IsNullOrEmpty(i.InvoiceBase.InvoiceNumber)) // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben.
{
if (i.InvoiceBase.InvoiceNumber == nextNumber)
//Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen
{
count++;
}
}
else
{
i.InvoiceBase.InvoiceNumber = nextNumber;
count++;
}
}
}
DAOFactory.GenericDAO.Insert(newInvoices);
inc.IncreaseInvoiceNumber(count, newInvoices);
return newInvoices.Select(i => i.Oid.Value).ToList();
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public InvoiceBaseDC LoadInvoiceBaseByOid(long invoiceBaseOid)
{
try
{
var r = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDC(
DAOFactory.GenericDAO.LoadByID<InvoiceBase>(invoiceBaseOid));
if (r.Type == InvoiceType.Settlement && r.SupportConceptOid != null)
{
SupportConcept sc = DAOFactory.GenericDAO.LoadByID<SupportConcept>(r.SupportConceptOid.Value);
r.CustomerFirstName = sc.Customer.Person.FirstName;
r.CustomerLastName = sc.Customer.Person.LastName;
}
return r;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public InvoiceNumberDC LoadInvoiceNumber()
{
try
{
var inr = DAOFactory.GenericDAO.LoadByID<InvoiceNumber>(1);
if (inr != null)
return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(inr);
return null;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public ServiceInvoiceDC LoadServiceInvoiceByOid(long serviceInvoiceOid)
{
try
{
var r = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(DAOFactory.GenericDAO.LoadByID<ServiceInvoice>(serviceInvoiceOid));
return r;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> UpdateInvoiceBases(List<InvoiceBaseDC> invoices)
{
try
{
var originals = DAOFactory.GenericDAO.LoadByIDs<InvoiceBase>(invoices.Select(i => i.InvoiceBaseOid.Value));
bool macheMerge = true;
foreach (var entity in originals)
{
var dc = invoices.Where(i => i.InvoiceBaseOid == entity.Oid).FirstOrDefault();
if (dc.IsPaid != entity.IsPaid ||
dc.IsExported != entity.IsExported ||
dc.IsReviewed != entity.IsReviewed ||
dc.IsSent != entity.IsSent ||
dc.PartialPayment != entity.PartialPayment)
{
//Kann nur über die Rechnungsübersicht geändert werden, daher kein Merge mit dem dc machen!
entity.IsPaid = dc.IsPaid;
entity.IsExported = dc.IsExported;
entity.IsReviewed = dc.IsReviewed;
entity.IsSent = dc.IsSent;
entity.PartialPayment = dc.PartialPayment;
macheMerge = false;
DAOFactory.GenericDAO.Update(entity);
}
}
if (macheMerge)
{
MapperFactory.InvoiceBaseDC_InvoiceBase.MergeWithEntitys(invoices, originals);
DAOFactory.GenericDAO.Update(originals);
}
return originals.Select(e => e.Version.Value).ToList();
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<long> SetInvoicePaid(List<InvoiceBaseDC> invoices, bool isPaid)
{
try
{
var originals = DAOFactory.GenericDAO.LoadByIDs<InvoiceBase>(invoices.Select(i => i.InvoiceBaseOid.Value));
foreach (var invoiceBase in originals)
{
invoiceBase.IsPaid = isPaid;
}
DAOFactory.GenericDAO.Update(originals);
return originals.Select(e => e.Version.Value).ToList();
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public InvoiceNumberDC UpdateInvoiceNumber(InvoiceNumberDC dc)
{
try
{
var old = DAOFactory.GenericDAO.LoadByID<InvoiceNumber>(1);
MapperFactory.InvoiceNumberDC_InvoiceNumber.MergeWithEntity(dc, old);
DAOFactory.GenericDAO.Update(old);
return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(old);
}
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)
{
try
{
var originals = DAOFactory.GenericDAO.LoadByIDs<SettlementInvoice>(invoices.Select(i => i.SettlementIvoiceOid.Value));
MapperFactory.SettlementDC_SettlementInvoice.MergeWithEntitys(invoices, originals);
//originals.ForEach(
// i =>
// {
//i.InvoiceBase.Type = InvoiceType.Settlement;
// We´ll add an invoiceitem, so we can treat a settlement like any other invoice
//i.InvoiceBase.InvoiceItems.Clear();
//i.InvoiceBase.InvoiceItems.Add(
// new InvoiceItem
// {
// AmountTotal = i.Claim,
// ItemPeriodStart = i.InvoiceBase.AccountingPeriodStart,
// ItemPeriodEnd = i.InvoiceBase.AccountingPeriodEnd,
// ItemDescription = "Spitzabrechung"
// });
//});
DAOFactory.GenericDAO.Update(originals);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceNumberDC> LoadInvoiceNumberList()
{
try
{
var numbers = DAOFactory.GenericDAO.GetAllActive<InvoiceNumber>();
return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDCs(numbers);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<InvoiceNumberDC> UpdateInvoiceNumberList(List<InvoiceNumberDC> dclist)
{
try
{
var numbers = DAOFactory.GenericDAO.GetAllActive<InvoiceNumber>();
MapperFactory.InvoiceNumberDC_InvoiceNumber.MergeWithEntitys(dclist, numbers);
DAOFactory.GenericDAO.Update(numbers);
return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDCs(numbers);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
#region GKV
public GkvAbrechnungDC GetGkvAbrechnung(long oid)
{
try
{
var gkv = DAOFactory.GenericDAO.GetByID<GkvAbrechnung>(oid);
var dc = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkv);
return dc;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<GkvAbrechnungDC> GetFilteredGkvAbrechnungen(GkvAbrechnungViewFilterDC gkvAbrechnungViewFilter)
{
try
{
if (gkvAbrechnungViewFilter == null || !gkvAbrechnungViewFilter.FilterTime)
return GetAllGkvAbrechnungen();
var start = gkvAbrechnungViewFilter.Start;
var end = gkvAbrechnungViewFilter.End;
var filter = gkvAbrechnungViewFilter.FilterForInvoiceDate;
var entities = DAOFactory.SearchDAO.GetGkvAbrechnungen(start, end, filter);
return MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDCs(entities);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public List<GkvAbrechnungDC> GetAllGkvAbrechnungen()
{
try
{
var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
var entries = DAOFactory.GenericDAO.GetAllActive<GkvAbrechnung>();
var dcs = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDCs(entries);
var updateables = dcs.Where(x => x.IsWaiting()).ToArray();
if (!updateables.Any())
return dcs;
var isUpToDate = SendApp8GetStatusRequest(updateables);
if (isUpToDate)
return dcs;
entries = DAOFactory.GenericDAO.GetAllActive<GkvAbrechnung>();
dcs = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDCs(entries);
return dcs;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public GkvAbrechnungCreateResponseDC CreateNewGkvAbrechnung(GkvAbrechnungCreateRequestDC request)
{
var response = new GkvAbrechnungCreateResponseDC();
try
{
var gkv_abrechnung = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewEntity(request.GkvAbrechnungDC);
if (gkv_abrechnung.AbrechnungsZeitraumEnde.Value.Hour == 0)
{
gkv_abrechnung.AbrechnungsZeitraumEnde = gkv_abrechnung.AbrechnungsZeitraumEnde.Value.Date.AddDays(1).AddMilliseconds(-1);
}
var orga = gkv_abrechnung.GetOrganisation();
gkv_abrechnung.Verfahrensstufe = orga.Verfahrensstufe;
decimal gesamt = 0;
foreach (var invoicebase_oid in request.SelectedInvoiceBases)
{
var service = DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoicebase_oid);
foreach (var peroid in service.ServiceInvoicePeriodList)
{
foreach (var invoice in peroid.InvoiceItemList)
{
gesamt += invoice.AmountTotal.Value;
}
}
}
gkv_abrechnung.Betrag = gesamt;
gkv_abrechnung.Bezahlt = false;
gkv_abrechnung.ErstelltAm = DateTime.Now;
DAOFactory.GenericDAO.Insert(gkv_abrechnung);
var gkv_abrechnung_dc = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkv_abrechnung);
response.Success = true;
response.GkvAbrechnungDC = gkv_abrechnung_dc;
}
catch (GkvException exc)
{
if (exc.Title.IsNotNullOrWhiteSpace())
response.TitleMessage = exc.Title;
response.Message = exc.Message;
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
return response;
}
public GkvAbrechnungDC UpdateGkvAbrechnung(GkvAbrechnungDC abrechnung)
{
try
{
var entity = DAOFactory.GenericDAO.GetByID<GkvAbrechnung>(abrechnung.GkvAbrechnungOid.Value);
MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MergeWithEntity(abrechnung, entity);
foreach (var invoice in entity.InvoiceBases)
{
invoice.IsPaid = entity.Bezahlt;
}
DAOFactory.GenericDAO.Update(entity);
return MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(entity);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public void DeleteGkvAbrechnung(GkvAbrechnungDC abrechnung)
{
try
{
ServiceLogic.SetActivationType<GkvAbrechnung>(abrechnung.GkvAbrechnungOid.Value, abrechnung.GkvAbrechnungVersion.Value, ActivationTypeId.Deleted);
}
catch (Exception e)
{
throw Utils.CreateBeWoFaultException(e);
}
}
public GkvAbrechnungSendResponseDC SendNewGkvAbrechnung(GkvAbrechnungSendRequestDC req)
{
var response = new GkvAbrechnungSendResponseDC();
var oid = req.GkvAbrechnungOid;
var entity = DAOFactory.GenericDAO.LoadByID<GkvAbrechnung>(oid);
var state = entity.GetState();
if (entity.IsWaiting() || state == GkvState.Paid)
{
response.Message = "Validierung fehlgeschlagen";
return response;
}
var protokoll = new GkvTransferProtokoll
{
ErstelltAm = DateTime.Now,
GkvAbrechnungOid = entity.Oid.Value
};
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;
MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MergeWithEntity(app8_protokoll, protokoll);
response.Success = app8_response.Success;
response.Message = app8_response.Message;
}
catch (GkvException de)
{
protokoll.ResultType = GkvTransferResultType.FailSoft;
protokoll.Fehlerdatum = DateTime.Now;
protokoll.Fehlernachricht = de.Message;
protokoll.Fehlertitel = de.Title ?? "Default";
}
catch (Exception e)
{
protokoll.ResultType = GkvTransferResultType.FailFatal;
protokoll.Fehlerdatum = DateTime.Now;
protokoll.Fehlernachricht = e.ToString();
protokoll.Fehlertitel = "Erstellung (kritisch)";
}
DAOFactory.GenericDAO.Update(entity);
response.TransferProtokoll = MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MapToNewDC(protokoll);
response.GkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(entity);
return response;
}
public GkvAbrechnungGetIKResponseDC SendGetIKRequest(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<GkvServerGetIKRequestDC, GkvServerGetIKResponseDC>(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
};
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)
{
throw Utils.CreateBeWoFaultException(e);
}
}
private void CreateGkvTransferProtokoll(long oid, GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll)
{
try
{
var manager = new DakotaManager();
var mandatordc = new OperationsServiceImp().GetMandator();
Validator.ValidateMandator(mandatordc);
var gkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkvAbrechnung);
var orgadc = gkvAbrechnungDC.Organisation;
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;
foreach (var invoicebase in gkvAbrechnung.InvoiceBases)
{
var service = DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoicebase.Oid.Value);
var orga2 = invoicebase.CostBearer2SupportConcept.CostBearer.Organisation;
var customer = invoicebase.CostBearer2SupportConcept.SupportConcept.Customer;
var invoicebase_dc = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDC(invoicebase);
var servicedc = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(service);
var customerdc = MapperFactory.CustomerDC_Customer.MapToNewDC(customer);
Validator.ValidateCustomer(customerdc);
manager.Add(servicedc, orgadc, customerdc, mandatordc, dat_short, tra_short);
}
manager.Apply();
if (manager.DakotaFileDict.Count != 1 || manager.DakotaFileDict.First().Value.GetKostenträgerCount() != 1)
{
var msg = "Unerwartete Anzahl an Dakota Files berechnet.";
MailUtils.SendGkvModuleErrorMail("CreateGkvTransferProtokoll", msg, Tenant);
throw new GkvException(msg);
}
var file_from_manager = manager.DakotaFileDict.First().Value;
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 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)
{
var msg = $"nutzdatendatei - Länger als 16777215: {nutzdatendatei.Length}";
MailUtils.SendGkvModuleErrorMail("CreateGkvTransferProtokoll", msg, Tenant);
throw new GkvException(msg);
}
protokoll.IKDatenannahmestelle = file_from_manager.GetIKDatenannahmestelle();
protokoll.IKKostentrager = file_from_manager.GetIKKostenträger();
protokoll.IKLeistungserbringer = file_from_manager.GetIKLeistungserbringer();
protokoll.IKKrankenkasse = file_from_manager.GetIKVersichertenKarte();
protokoll.Rechnungsnummer = file_from_manager.GetRechnungsnummer();
protokoll.Auftragsdatei = file_from_manager.GetAuftragsdatei();
protokoll.Nutzdatendatei = nutzdatendatei;
protokoll.Transfername = file_from_manager.GetTransferName();
protokoll.Dateigrosse = nutzdatendatei.Length;
protokoll.Dateityp = "Nutzdatendatei";
protokoll.Dateiname = protokoll.Transfername;
protokoll.AbsenderBezeichnung = "ownSoft GmbH";
protokoll.EmpfangerBezeichnung = orgadc.BezDatenannahmestelle;
}
catch (GkvException de)
{
if (string.IsNullOrEmpty(de.Title))
de.Title = "Protokoll Erstellung";
throw de;
}
catch (Exception e)
{
MailUtils.SendGkvModuleErrorMail("CreateGkvTransferProtokoll", e, Tenant);
throw new GkvException(e.Message, "Erstellung");
}
}
private Tuple<int, int> GetNextDatenaustauschreferenzTransfernummer(GkvAbrechnung gkvAbrechnung, string datenannahmestelle)
{
var datenaustauschref = DAOFactory.SearchDAO.GetNextDatenaustauschreferenz(datenannahmestelle);
int transfernummer;
var state = gkvAbrechnung.GetState();
if (state == GkvState.NoSend)
{
transfernummer = DAOFactory.SearchDAO.GetNextTransfernummer(datenannahmestelle);
}
else if (state == GkvState.ErrorSoft || state == GkvState.ErrorFatal || state == GkvState.ErrorFolgefehler)
{
transfernummer = gkvAbrechnung.GkvTransferProtokolle.Last().Transfernummer;
}
else
{
throw new ArgumentException("Versucht Transfernummer zu laden, invalid state", nameof(state));
}
return new Tuple<int, int>(datenaustauschref, transfernummer);
}
private Tuple<int, int> ClearDatenaustauschreferenzTransfernummer(int datenaustauschreferenz, int transfernummer)
{
int d = datenaustauschreferenz % 99999;
int t = transfernummer % 1000;
if (d == 0)
{
d = 99999;
}
return new Tuple<int, int>(d, t);
}
private GkvServerSendNewResponseDC SendApp8SendNewRequest(GkvTransferProtokoll protokoll)
{
var gkv_transfer_dc = MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MapToNewDC(protokoll);
var request_app8 = new GkvServerSendNewRequestDC
{
Protokoll = gkv_transfer_dc
};
var response_app8 = SendApp8Request<GkvServerSendNewRequestDC, GkvServerSendNewResponseDC>(request_app8);
if (!response_app8.Success)
throw new GkvException(response_app8.Message);
return response_app8;
}
/// <summary>
///
/// </summary>
/// <param name="updateables"></param>
/// <param name="loginName"></param>
/// <param name="hashed_password"></param>
/// <returns>Returns true, if the states are all up to date. False otherwise.</returns>
private bool SendApp8GetStatusRequest(GkvAbrechnungDC[] updateables)
{
var updateables_len = updateables.Count();
var request = new GkvServerGetStatusRequestDC
{
Tenant = MultitenancyOperationContextExt.Current.Tenant,
Oids = new long[updateables_len]
};
for (int id = 0; id < updateables_len; id++)
{
var gkv_abrechnung = updateables[id];
var gkv_transfer = gkv_abrechnung.TransferProtokolle.Last();
request.Oids[id] = gkv_transfer.GkvTransferProtokollOid.Value;
}
GkvServerGetStatusResponseDC response_app8;
try
{
response_app8 = SendApp8Request<GkvServerGetStatusRequestDC, GkvServerGetStatusResponseDC>(request);
}
catch (Exception 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);
var results = response_app8.Results.Where(x => x is object);
if (!results.Any())
return true;
HandleGkvServerResults(results);
return false;
}
public void HandleGkvServerResults(IEnumerable<GkvServerResultDC> results)
{
var protokolls = new List<GkvTransferProtokoll>();
foreach (var result in results)
{
var protokoll = DAOFactory.GenericDAO.GetByID<GkvTransferProtokoll>(result.ProtokollOid);
protokoll.ResultType = result.ResultType;
protokoll.Fehlertitel = result.Titel;
protokoll.Fehlerdatum = result.Datum;
protokoll.Fehlernachricht = result.Nachricht;
switch (result.ResultType)
{
case GkvTransferResultType.Success:
protokoll.SentDakotaSuccess = true;
break;
case GkvTransferResultType.FailSoft:
protokoll.SentApp8Success = false;
break;
case GkvTransferResultType.FailFatal:
protokoll.SentApp8Success = false;
break;
case GkvTransferResultType.FailFollowUp:
protokoll.SentApp8Success = false;
break;
}
protokolls.Add(protokoll);
}
if(protokolls.Any())
DAOFactory.GenericDAO.Update(protokolls);
var follows = results.Where(x => x.ResultType == GkvTransferResultType.FailFollowUp);
if (follows.Any())
{
foreach (var follow in follows)
{
var protokoll_oid = follow.ProtokollOid;
var protokoll = DAOFactory.GenericDAO.LoadByID<GkvTransferProtokoll>(protokoll_oid);
var abrechnung_oid = protokoll.GkvAbrechnungOid;
var new_req = new GkvAbrechnungSendRequestDC()
{
GkvAbrechnungOid = abrechnung_oid
};
var res = SendNewGkvAbrechnung(new_req);
if (!res.Success)
throw new GkvException("Success - " + res.Message);
}
}
}
private Res SendApp8Request<Req, Res>(Req request) where Req : GkvRequestDC where Res : GkvResponseDC
{
var user = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser;
if (user == null)
{
throw new GkvException("User unbekannt", "KundenApp");
}
request.Username = user.LoginName;
request.Password = user.BCryptPassword;
request.Tenant = MultitenancyOperationContextExt.Current.Tenant;
if(request is GkvServerSendNewRequestDC send_new_req)
{
send_new_req.ApplicationUserOid = user.Oid.Value;
}
return GkvSender.SendApp8Request<Req, Res>(request, request.Tenant);
}
#endregion
}
}