Files
BeWoPlaner/Service/ServiceImplementations/AccountingServiceImp.cs

1230 lines
47 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;
namespace BeWo.Service.ServiceImplementations
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class AccountingServiceImp : IAccountingService
{
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> 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)
{
var acc = PluginLoader.FindClass<AccountingService>();
return acc.UpdateServiceInvoices(invoices);
}
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 GkvAbrechnungResponseDC CreateNewGkvAbrechnung(GkvAbrechnungRequestDC request)
{
var response = new GkvAbrechnungResponseDC();
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);
var invoicebase = DAOFactory.GenericDAO.GetByID<InvoiceBase>(invoicebase_oid);
var invoicebase_dc = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDC(invoicebase);
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;
return response;
}
catch (DakotaException exc)
{
response.Error = 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);
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();
response.Successful = false;
var oid = req.GkvAbrechnungOid;
var entity = DAOFactory.GenericDAO.LoadByID<GkvAbrechnung>(oid);
var state = GkvAbrechnung.GetState(entity);
if (state == GkvState.Waiting || state == GkvState.OldAndNoFeedback || state == GkvState.Paid)
{
response.Message = "Validierung fehlgeschlagen";
return response;
}
var protokoll = new GkvTransferProtokoll();
protokoll.ErstelltAm = DateTime.Now;
protokoll.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.Successful = app8_response.Success;
}
catch (DakotaException de)
{
protokoll.Fehlerdatum = DateTime.Now;
protokoll.Fehlerlevel = GkvTransferFehlerlevel.Soft;
protokoll.Fehlernachricht = de.Message;
protokoll.Fehlertitel = de.Title ?? "Default";
}
catch (Exception e)
{
protokoll.Fehlerdatum = DateTime.Now;
protokoll.Fehlerlevel = GkvTransferFehlerlevel.Fatal;
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;
}
private void CreateGkvTransferProtokoll(long oid, GkvAbrechnung gkvAbrechnung, GkvTransferProtokoll protokoll)
{
try
{
var manager = new DakotaManager();
var mandatordc = new OperationsServiceImp().GetMandator();
DakotaValidator.ValidateMandator(mandatordc);
var orga = gkvAbrechnung.GetOrganisation();
DakotaValidator.ValidateOrganisation(orga);
if (!DakotaValidator.ValidateOrganisationInformations(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;
orga.BezDatenannahmestelle = res.BezDatenannahmestelle;
if (!DakotaValidator.ValidateOrganisationInformations(orga))
throw new DakotaException($"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<GkvAbrechnung>(oid);
}
var gkvAbrechnungDC = MapperFactory.GkvAbrechnungDC_GkvAbrechnung.MapToNewDC(gkvAbrechnung);
var orgadc = gkvAbrechnungDC.Organisation;
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);
DakotaValidator.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)
{
throw new DakotaException("Unerwartete Anzahl an Dakota Files berechnet.");
}
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 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)
{
throw new DakotaException($"nutzdatendatei - Länger als 65535: {nutzdatendatei.Length}");
}
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 = orga.BezDatenannahmestelle;
}
catch (DakotaException de)
{
if (string.IsNullOrEmpty(de.Title))
de.Title = "Protokoll Erstellung";
throw de;
}
catch (Exception e)
{
throw new DakotaException(e.Message, "Erstellung");
}
}
private Tuple<int, int> GetNextDatenaustauschreferenzTransfernummer(GkvAbrechnung gkvAbrechnung, string datenannahmestelle)
{
var datenaustauschref = DAOFactory.SearchDAO.GetNextDatenaustauschreferenz(datenannahmestelle);
int transfernummer;
var state = GkvAbrechnung.GetState(gkvAbrechnung);
if (state == GkvState.NoSend)
{
transfernummer = DAOFactory.SearchDAO.GetNextTransfernummer(datenannahmestelle);
}
else if (state == GkvState.Error || state == GkvState.ErrorFatal)
{
transfernummer = gkvAbrechnung.GkvTransferProtokolle.Last().Transfernummer;
}
else
{
throw new ArgumentException("Versucht Datenaustauschref 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 GkvApp8SendNewResponse SendApp8SendNewRequest(GkvTransferProtokoll protokoll)
{
var gkv_transfer_dc = MapperFactory.GkvTransferProtokollDC_GkvTransferprotokoll.MapToNewDC(protokoll);
var url = "https://app8.bewoplaner.de/service/GkvAbrechnungView.aspx";
#if DEBUG
//url = "http://localhost:3777/Host/GkvAbrechnungView.aspx";
#endif
var request_app8 = new GkvApp8SendNewRequest
{
SendDirect = true,
GkvTransferProtokoll = gkv_transfer_dc
};
#if DEBUG
request_app8.SendDirect = false;
#endif
var response_app8 = SendApp8Request<GkvApp8SendNewRequest, GkvApp8SendNewResponse>(url, request_app8);
if (!response_app8.Success)
throw new DakotaException(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 url = "https://app8.bewoplaner.de/service/GkvAbrechnungView.aspx";
var request = new GkvApp8GetStatusRequest
{
Tenant = MultitenancyOperationContextExt.Current.Tenant,
Oids = new long[updateables_len],
DebugMode = "fozc4897b6ztvf978AFCRRG244fvFV2532fvf324AF",
};
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;
}
GkvApp8GetStatusResponse response_app8;
try
{
response_app8 = SendApp8Request<GkvApp8GetStatusRequest, GkvApp8GetStatusResponse>(url, request);
}
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++)
{
var gkv_abrechnung = updateables[id];
var fehler = response_app8.Fehler[id];
if (fehler is null)
continue;
allAreUpToDate = false;
var gkv_abrechnung_entity = DAOFactory.GenericDAO.LoadByID<GkvAbrechnung>(gkv_abrechnung.GkvAbrechnungOid.Value);
var protokoll = gkv_abrechnung_entity.GkvTransferProtokolle.First(x => x.Oid == fehler.Oid);
protokoll.Fehlerdatum = fehler.Datum;
protokoll.Fehlerlevel = fehler.Level;
protokoll.Fehlernachricht = fehler.Nachricht;
protokoll.Fehlertitel = fehler.Titel;
DAOFactory.GenericDAO.Update(gkv_abrechnung_entity);
}
return allAreUpToDate;
}
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<GkvApp8GetIKRequest, GkvApp8GetIKResponse>(url, request);
}
private T2 SendApp8Request<T, T2>(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<T2>(SendApp8Request(url, JsonConvert.SerializeObject(request)));
}
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 DakotaException(e.Message, "App8");
}
if (string.IsNullOrEmpty(response_app8_str))
throw new DakotaException("Leere Antwort", "App8");
return response_app8_str;
}
#endregion
}
}