Files
BeWoPlaner/ReportImp/LebenshilfeFrankfurtOder/Invoicing/WstInvoiceCreation.cs
Christian 7324b78f9b LH Frankfurt Oder: Anpassungen Rechnung für Wohnstätten
Pas: Anpassung Stundenkonto für die Jahresansicht
Frau Hildmann, Anspassung Kalkulation
2026-03-10 00:30:24 +01:00

516 lines
18 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Invoicing;
using BeWo.Service.Plugins;
using BeWo.Service.ServiceImplementations;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
using LebenshilfeFrankfurtOder.BesondereWohnform;
namespace LebenshilfeFrankfurtOder.Invoicing
{
public class WstInvoiceCreation : InvoiceCreation
{
private Dictionary<String, decimal> category2Tagessatz = null;
private Dictionary<String, String> category2ServiceDescription = null;
public override void SetInvoiceId(ServiceInvoice invoice)
{
invoice.InvoiceBase.InvoiceId = "RechnungWst";
invoice.InvoiceBase.InvoiceTypeText = "Wohnstätte";
}
public override List<ServiceInvoiceDC> GenerateServiceInvoices(long costBearerOid, DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
category2Tagessatz = new Dictionary<String, decimal>();
category2ServiceDescription = new Dictionary<String, String>();
var daten = CreateAbrechnungsdaten(invoicePeriod, supportConcepts2ServiceRecords);
var invoiceList = CreateInvoices(invoicePeriod, daten);
return invoiceList.Select(item => MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(item)).ToList();
}
private IList<ServiceInvoice> CreateInvoices(DateTimeSpan invoicePeriod, IList<WstRechnungsdaten> daten)
{
var invoiceList = new List<ServiceInvoice>();
var invoiceCounter = 0;
foreach (var trd in daten)
{
var i = CreateInvoice(invoiceCounter, invoicePeriod, trd);
var c = i.GetTotalClaim();
if (c.HasValue && c.Value > 0)
{
invoiceList.Add(i);
invoiceCounter++;
}
}
return invoiceList;
}
private ServiceInvoice CreateInvoice(int invoiceCounter, DateTimeSpan invoicePeriod, WstRechnungsdaten trd)
{
var invoice = new ServiceInvoice();
SetInvoiceId(invoice);
SetRecipientInformation(invoice, trd.CostBearer);
if (trd.SupportConcepts != null && trd.SupportConcepts.Count > 0)
{
foreach (var ts in trd.SupportConcepts)
{
if (ts.CostBearer2SupportConcept != null &&
ts.CostBearer2SupportConcept.CostBearerContactPerson != null)
{
if (ts.CostBearer2SupportConcept.CostBearerContactPerson.Sex.HasValue &&
ts.CostBearer2SupportConcept.CostBearerContactPerson.Sex.Value == Sex.Male)
{
invoice.InvoiceBase.RecipientPersonFirstName = "Herr ";
}
else if (ts.CostBearer2SupportConcept.CostBearerContactPerson.Sex.HasValue &&
ts.CostBearer2SupportConcept.CostBearerContactPerson.Sex.Value == Sex.Female)
{
invoice.InvoiceBase.RecipientPersonFirstName = "Frau ";
}
else
{
invoice.InvoiceBase.RecipientPersonFirstName = "";
}
invoice.InvoiceBase.RecipientPersonFirstName += ts.CostBearer2SupportConcept.CostBearerContactPerson.FirstName;
invoice.InvoiceBase.RecipientPersonLastName = ts.CostBearer2SupportConcept.CostBearerContactPerson.LastName;
}
}
}
SetSenderInformation(invoice);
SetInvoiceBaseData(invoiceCounter, invoice, trd.CostBearer, invoicePeriod, new List<CompactSupportConceptDC>());
foreach (var tsc in trd.SupportConcepts)
{
SetServiceInvoicePeriods(invoice, tsc, invoicePeriod);
}
SetServiceInvoicePeriodAmounts(invoice);
// Spitzabrechnung
if (invoicePeriod == null)
{
SetAmountAdvancePayments(invoice);
}
return invoice;
}
public override void SetSenderInformation(ServiceInvoice serviceInvoice)
{
ApplicationUser user = null;
if (LoggedInUserOperationContextExt.Current != null)
{
user = LoggedInUserOperationContextExt.Current.User;
}
else
{
user = SessionFacade.LoggedInUser;
}
var mandator = new OperationsServiceImp().GetMandator2(false);
serviceInvoice.InvoiceBase.SenderAddress = new Address
{
Street = mandator.Street,
PostalCode = mandator.PostalCode,
Town = mandator.Town,
State = mandator.State
};
if (user != null)
{
serviceInvoice.InvoiceBase.CreatorFirstName = serviceInvoice.InvoiceBase.SenderFirstName = user.Employee.Person.FirstName;
serviceInvoice.InvoiceBase.CreatorLastName = serviceInvoice.InvoiceBase.SenderLastName = user.Employee.Person.LastName;
serviceInvoice.InvoiceBase.SenderContacts = user.Employee.Person.Contacts.Select(i => i.CopyToNew()).ToList();
}
}
private void SetServiceInvoicePeriods(ServiceInvoice invoice, WstSupportConcept tsc, DateTimeSpan invoicePeriod)
{
var invoiceAccountingPeriodSpan = new DateTimeSpan
{
StartDateTime = invoice.InvoiceBase.AccountingPeriodStart.Value,
EndDateTime = invoice.InvoiceBase.AccountingPeriodEnd.Value
};
if (tsc.SupportConceptApprovalPeriod != null)
{
SupportConceptApprovalPeriodDC approvalPeriodDC = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(tsc.SupportConceptApprovalPeriod);
ServiceInvoicePeriod serviceInvoicePeriod = CreateServiceInvoicePeriod(approvalPeriodDC, invoiceAccountingPeriodSpan);
serviceInvoicePeriod.SupportConceptApprovalPeriod = tsc.SupportConceptApprovalPeriod;
serviceInvoicePeriod.Customer = tsc.CostBearer2SupportConcept.SupportConcept.Customer;
CostBearer costBearer = tsc.CostBearer2SupportConcept.CostBearer;
List<CostRatePeriodDC> costRates = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(costBearer.CostRatePeriods);
CostRatePeriodDC serviceUnit = costRates.GetCostRatePeriodForDate(CostRatePeriodType.MinutesPerServiceUnit, DateTime.Now);
serviceInvoicePeriod.ServiceUnitName = serviceUnit.UnitName;
var itemList = CreateInvoiceItems(invoice, serviceInvoicePeriod, invoicePeriod, serviceInvoicePeriod.SupportConceptApprovalPeriod);
serviceInvoicePeriod.InvoiceItemList.AddRange(itemList);
if (serviceInvoicePeriod.InvoiceItemList.Count > 0)
invoice.ServiceInvoicePeriodList.Add(serviceInvoicePeriod);
}
}
private IList<WstRechnungsdaten> CreateAbrechnungsdaten(DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
var key2Rd = new Dictionary<string, WstRechnungsdaten>();
var daten = new List<WstRechnungsdaten>();
foreach (var iSupportConcept2ServiceRecords in supportConcepts2ServiceRecords)
{
var sc = iSupportConcept2ServiceRecords.Key;
var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(sc.CostBearerRelOids[0]);
var ap = c2s.CostBearerContactPerson;
long oOid = c2s.CostBearer.Organisation.Oid.Value;
long pOid = 0;
if (ap != null)
{
pOid = ap.Oid.Value;
}
WstSupportConcept tsc = new WstSupportConcept();
tsc.SupportConcept = sc;
tsc.CostBearer2SupportConcept = c2s;
foreach (var scap in c2s.ApprovalPeriodList)
{
if (scap.StartDate < invoicePeriod.EndDate && scap.EndDate >= invoicePeriod.StartDate && scap.ServiceCategory != null)
{
String name = scap.ServiceCategory.Name.ToLower().Trim();
if (name.Contains("pw110840"))
{
tsc.SupportConceptApprovalPeriod = scap;
}
}
}
String key = String.Format("{0}_{1}", oOid, pOid);
WstRechnungsdaten td = null;
if (!key2Rd.ContainsKey(key))
{
td = new WstRechnungsdaten();
td.CostBearer = c2s.CostBearer;
td.Ansprechpartner = ap;
td.SupportConcepts = new List<WstSupportConcept>();
key2Rd.Add(key, td);
daten.Add(td);
}
else
{
td = key2Rd[key];
}
td.SupportConcepts.Add(tsc);
}
return daten;
}
private List<InvoiceItem> CreateInvoiceItems(ServiceInvoice invoice, ServiceInvoicePeriod sip, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap)
{
sip.ApprovedFixedAmount = 0;
List<InvoiceItem> list = new List<InvoiceItem>();
DateTime dt = invoicePeriod.StartDate;
var bookings = DAOFactory.SearchDAO.GetAdditionalServiceBookingsForCustomer(sip.Customer.Oid.Value, invoicePeriod.StartDate, invoicePeriod.EndDate);
var absenceTimeDCs = MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(sip.Customer.AbsenceTimes);
var cat = new CustomerAbsenceTimes(absenceTimeDCs, invoicePeriod.StartDate);
while (dt <= invoicePeriod.EndDate)
{
list.Add(CreateInvoiceItem(dt, scap, bookings, sip.Customer, cat));
dt = dt.AddDays(1);
}
return list;
}
private InvoiceItem CreateInvoiceItem(DateTime dt, SupportConceptApprovalPeriod scap, IEnumerable<AdditionalServiceBooking> bookings, Customer c, CustomerAbsenceTimes cat)
{
var invoiceItem = new InvoiceItem();
decimal ts = 0;
String serviceName = "";
var at = GetAbsenceTime(dt, c.AbsenceTimes);
if (at != null)
{
var name = at.AbsenceReason.Description.ToLower();
if (name.Contains("(u)"))
{
invoiceItem.UnitDescription = "U";
}
else if (name.Contains("(k)"))
{
invoiceItem.UnitDescription = "K";
}
else if (name.Contains("(uf)"))
{
invoiceItem.UnitDescription = "UF";
}
else if (name.Contains("(ah)"))
{
invoiceItem.UnitDescription = "AH";
}
else if (name.Contains("(ak)"))
{
invoiceItem.UnitDescription = "AK";
}
else if (name.Contains("(kh)"))
{
invoiceItem.UnitDescription = "KH";
}
else if (name.Contains("(au)"))
{
invoiceItem.UnitDescription = "AU";
}
else if (name.Contains("(ac)"))
{
invoiceItem.UnitDescription = "AC";
}
if (cat.TagWirdAlsAbwesendBerechnet(dt))
{
GetTagessatz(dt, scap, true, out ts, out serviceName);
}
}
if (String.IsNullOrEmpty(invoiceItem.UnitDescription))
{
invoiceItem.UnitDescription = "I";
}
if (ts == 0)
{
GetTagessatz(dt, scap, false, out ts, out serviceName);
}
invoiceItem.AmountPerUnit = ts;
invoiceItem.UnitCount = 1;
invoiceItem.AmountTotal = ts;
invoiceItem.ItemPeriodStart = dt;
invoiceItem.ItemPeriodEnd = dt;
invoiceItem.GrossAmountTotal = ts;
invoiceItem.AccountingInterval = AccountingIntervalType.Daily;
invoiceItem.ItemDescription = serviceName;
if (scap != null)
{
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
}
return invoiceItem;
}
//private bool MussAbwesenheitAbrechnen(AbsenceTime at, DateTime dt)
//{
// if (IstAusserHausAbwesenheit(at) && IsAbsenceCountGreater3(at, dt))
// {
// return true;
// }
// return false;
//}
private bool IsAbsenceCountGreater3(AbsenceTime at, DateTime monat)
{
DateTime monatStart = new DateTime(monat.Year, monat.Month, 1);
DateTime monatEnde = monatStart.AddMonths(1);
if (at.Start.HasValue && at.Start.Value < monatEnde && (!at.End.HasValue || at.End.Value >= monatStart))
{
DateTime dt = at.Start.Value;
DateTime ende = monatEnde.AddMonths(1); // nächstenMonat mit berücksichtigen um Abwesenheiten zu prüfen, die in den nächsten Monat mit hineingehen
if (at.End.HasValue && at.End.Value < ende)
{
ende = at.End.Value;
}
int tageAbwesendInsgesamt = 0;
int tageAbwesendImMonat = 0;
while (dt < ende)
{
tageAbwesendInsgesamt++;
if (dt.Month == monat.Month)
{
tageAbwesendImMonat++;
}
dt = dt.AddDays(1);
}
if (tageAbwesendInsgesamt > 3)
{
return true;
}
}
return false;
}
private bool IstAusserHausAbwesenheit(AbsenceTime at)
{
String name = at.AbsenceReason.Description.ToLower();
if (name.Contains("(ah)") || name.Contains("(ak)") || name.Contains("(kh)") || name.Contains("(au)") || name.Contains("(ac)"))
{
return true;
}
return false;
}
private AbsenceTime GetAbsenceTime(DateTime dt, IList<AbsenceTime> absenceTimes)
{
foreach (var at in absenceTimes)
{
if (IstWstAbwesenheit(at) && at.Start.HasValue && at.Start.Value.Date <= dt && (!at.End.HasValue || at.End.Value.Date >= dt))
{
return at;
}
}
return null;
}
private bool IstWstAbwesenheit(AbsenceTime at)
{
var name = at.AbsenceReason.Description;
if (name.Contains("WST"))
{
return true;
}
return false;
}
private void GetTagessatz(DateTime dt, SupportConceptApprovalPeriod scap, bool istAbwesend, out decimal tagessatz, out String sericeName)
{
tagessatz = 0;
sericeName = "";
if (scap.ServiceCategory != null)
{
String key = String.Format("{0}_{1}", scap.ServiceCategory.Oid.Value, istAbwesend ? 0 : 1);
if (!category2Tagessatz.ContainsKey(key))
{
var descList = DAOFactory.SearchDAO.FindServiceDescriptionForCategory(scap.ServiceCategory.Oid.Value);
foreach (var sd in descList)
{
decimal ts = 0;
var crps = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(sd.CostRatePeriods);
var cr = crps.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, dt);
if (cr != null && cr.CostRateValue.HasValue)
{
ts = cr.CostRateValue.Value;
}
String newkey = String.Format("{0}_{1}", scap.ServiceCategory.Oid.Value, 1);
if (sd.Name.Contains("ABW"))
{
newkey = String.Format("{0}_{1}", scap.ServiceCategory.Oid.Value, 0);
}
if (!category2Tagessatz.ContainsKey(newkey))
{
category2Tagessatz.Add(newkey, ts);
}
if (!category2ServiceDescription.ContainsKey(newkey))
{
category2ServiceDescription.Add(newkey, sd.Name);
}
}
}
if (category2Tagessatz.ContainsKey(key))
{
tagessatz = category2Tagessatz[key];
}
if (category2ServiceDescription.ContainsKey(key))
{
sericeName = category2ServiceDescription[key];
}
}
}
}
public class WstRechnungsdaten
{
public CostBearer CostBearer { get; set; }
//public Organisation Organisation { get; set; }
public Person Ansprechpartner { get; set; }
public IList<WstSupportConcept> SupportConcepts { get; set; }
}
public class WstSupportConcept
{
public CompactSupportConceptDC SupportConcept { get; set; }
public CostBearer2SupportConcept CostBearer2SupportConcept { get; set; }
public SupportConceptApprovalPeriod SupportConceptApprovalPeriod { get; set; }
}
}