403 lines
17 KiB
C#
403 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Service.DCEntityMapper;
|
|
using BeWo.Service.Invoicing;
|
|
using BeWo.Service.Plugins;
|
|
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 DevExpress.Data.Filtering.Helpers;
|
|
|
|
namespace InputFamilienhilfe.Invoicing
|
|
{
|
|
public class DefaultInvoiceCreation : InvoiceCreation
|
|
{
|
|
private const decimal FAHRTKOSTEN = 0.3m;
|
|
private DateTime? accountingPeriodStart = null;
|
|
private DateTime? accountingPeriodEnd = null;
|
|
private decimal organisationRateFactor = 0;
|
|
|
|
public override void SetInvoiceId(ServiceInvoice invoice)
|
|
{
|
|
invoice.InvoiceBase.InvoiceId = "Rechnung";
|
|
invoice.InvoiceBase.InvoiceTypeText = "Rechnung";
|
|
}
|
|
|
|
|
|
|
|
public override void SetInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer, DateTimeSpan invoicePeriod,
|
|
IList<CompactSupportConceptDC> supportConceptList)
|
|
{
|
|
if (invoicePeriod != null)
|
|
{
|
|
accountingPeriodStart = invoicePeriod.StartDate;
|
|
accountingPeriodEnd = invoicePeriod.EndDate;
|
|
organisationRateFactor = GetRateFactor(costBearer, invoicePeriod.StartDate);
|
|
}
|
|
base.SetInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConceptList);
|
|
}
|
|
|
|
public override List<ServiceInvoiceDC> GenerateServiceInvoices(long costBearerOid, DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
|
|
{
|
|
var list = base.GenerateServiceInvoices(costBearerOid, invoicePeriod, supportConcepts2ServiceRecords);
|
|
|
|
foreach (var si in list)
|
|
{
|
|
if (si.ServiceInvoicePeriods != null)
|
|
{
|
|
foreach (var sip in si.ServiceInvoicePeriods)
|
|
{
|
|
if (sip.InvoiceItems != null && sip.InvoiceItems.Count == 1 &&
|
|
sip.InvoiceItems[0].AccountingInterval.HasValue &&
|
|
sip.InvoiceItems[0].AccountingInterval.Value == AccountingIntervalType.FlatRate)
|
|
{
|
|
var ii = sip.InvoiceItems[0];
|
|
|
|
if (String.IsNullOrEmpty(ii.ItemDescription))
|
|
{
|
|
if (sip.SupportConceptApprovalPeriod != null &&
|
|
sip.SupportConceptApprovalPeriod.ServiceCategory != null)
|
|
{
|
|
ii.ItemDescription = sip.SupportConceptApprovalPeriod.ServiceCategory.Name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
private decimal GetRateFactor(CostBearer costBearer, DateTime date)
|
|
{
|
|
var cpDcList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(costBearer.CostRatePeriods);
|
|
var cp = cpDcList.GetCostRatePeriodForDate(CostRatePeriodType.RateFactor, date);
|
|
if (cp != null && cp.CostRateValue.HasValue)
|
|
{
|
|
var rf = cp.CostRateValue.Value;
|
|
if (Math.Round(rf, 2) == 33.33m)
|
|
{
|
|
rf = 100m / 3m;
|
|
}
|
|
return rf;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc)
|
|
{
|
|
var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);
|
|
if (list.Count > 0)
|
|
{
|
|
var items = CreateFahrtkostenItems(serviceRecordsInPeriod);
|
|
list.AddRange(items);
|
|
}
|
|
|
|
var iilist = CreateSonstigeKosten(scap, calc, serviceRecordsInPeriod, invoicePeriod);
|
|
iilist = (List<InvoiceItem>)CreateSummaryInvoiceItems(iilist, invoicePeriod, scap, calc, false, false);
|
|
list.AddRange(iilist);
|
|
|
|
return list;
|
|
}
|
|
|
|
public override void CreateFixedAmounts(ServiceInvoicePeriod serviceInvoicePeriod, SupportConceptApprovalPeriodDC supportConceptApprovalPeriod, CostBearer2SupportConcept cb2sc)
|
|
{
|
|
base.CreateFixedAmounts(serviceInvoicePeriod, supportConceptApprovalPeriod, cb2sc);
|
|
|
|
// AB, 10.03.2025 - Weitere Rechnungspositionen für Tagesbetreuung
|
|
if (serviceInvoicePeriod.Start.HasValue && serviceInvoicePeriod.Start.Value > new DateTime(2024, 06, 30)
|
|
&& supportConceptApprovalPeriod.ServiceCategory != null && supportConceptApprovalPeriod.ServiceCategory.Name == "Tagesbetreuung")
|
|
{
|
|
List<ServiceDescriptionDC> serviceDescriptions = new List<ServiceDescriptionDC>();
|
|
var start = serviceInvoicePeriod.Start.Value;
|
|
var descAuslagenDC = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(DAOFactory.GenericDAO.GetByID<ServiceDescription>(90)); // Sonstige Auslagen
|
|
serviceDescriptions.Add(descAuslagenDC);
|
|
var descBereitstellungDC = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(DAOFactory.GenericDAO.GetByID<ServiceDescription>(91)); // Bereitstellung Zimmer
|
|
serviceDescriptions.Add(descBereitstellungDC);
|
|
|
|
foreach (var sd in serviceDescriptions)
|
|
{
|
|
var crpValue = sd.CostRatePeriods.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, start);
|
|
var ii = serviceInvoicePeriod.InvoiceItemList.FirstOrDefault();
|
|
ii.ItemDescription = "Tagesbetreuung";
|
|
serviceInvoicePeriod.InvoiceItemList.Add(new InvoiceItem
|
|
{
|
|
UnitCount = ii.UnitCount,
|
|
AmountPerUnit = crpValue.CostRateValue,
|
|
AmountTotal = crpValue.CostRateValue,
|
|
ItemPeriodStart = ii.ItemPeriodStart,
|
|
ItemPeriodEnd = ii.ItemPeriodEnd,
|
|
GrossAmountTotal = crpValue.CostRateValue,
|
|
AccountingInterval = ii.AccountingInterval,
|
|
ItemDescription = sd.Name
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void SetServiceInvoicePeriodAmounts(ServiceInvoice invoice)
|
|
{
|
|
foreach (ServiceInvoicePeriod iPeriod in invoice.ServiceInvoicePeriodList)
|
|
{
|
|
iPeriod.Claim = 0;
|
|
// Mehrere InvoiceItems für Tagesbetreuung
|
|
//if (iPeriod.ApprovedFixedAmount.HasValue && iPeriod.ApprovedFixedAmount.Value != 0)
|
|
// iPeriod.Claim = iPeriod.ApprovedFixedAmount;
|
|
//else
|
|
//{
|
|
foreach (InvoiceItem item in iPeriod.InvoiceItemList)
|
|
{
|
|
if (item.GrossAmountTotal.HasValue)
|
|
iPeriod.Claim += item.GrossAmountTotal;
|
|
}
|
|
//}
|
|
iPeriod.Claim = Math.Round(iPeriod.Claim.Value, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
}
|
|
|
|
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
|
|
{
|
|
var ii = base.CreateInvoiceItem(iServiceRecord, scap, calc);
|
|
if (iServiceRecord.ServiceDescription.CategoryName.Contains("Betreuter Umgang"))
|
|
{
|
|
ii.RateFactor = 100m / 3m;
|
|
ii.GrossAmountTotal = ii.AmountTotal + (ii.AmountTotal * ii.RateFactor / 100);
|
|
}
|
|
|
|
if (!ii.UnitCount.HasValue || ii.UnitCount.Value == 0)
|
|
{
|
|
if (!ii.GrossAmountTotal.HasValue || ii.GrossAmountTotal.Value == 0)
|
|
{
|
|
return null;
|
|
}
|
|
int test = 0;
|
|
}
|
|
RenameServiceName(ii);
|
|
|
|
return ii;
|
|
}
|
|
|
|
public override void CheckMaxApprovedAmount(ServiceInvoice invoice, ServiceInvoicePeriod sip, SupportConceptApprovalPeriodDC scap, CostBearer2SupportConcept costBearer2SupportConcept, DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
|
|
{
|
|
return;
|
|
// AB, 10.03.2025: auskommentiert, da Rest nie verwendet wurde!
|
|
//if (sip.ApprovedHours.HasValue && !scap.IsApprovedBEShifting)
|
|
//{
|
|
// decimal totalHours = 0;
|
|
|
|
// foreach (var ii in sip.InvoiceItemList.Where(ii => ii.UnitCount.HasValue))
|
|
// {
|
|
// if (totalHours + ii.UnitCount.Value > sip.ApprovedHours)
|
|
// {
|
|
// ii.UnitCount = sip.ApprovedHours.Value - totalHours;
|
|
// if (ii.AmountPerUnit.HasValue)
|
|
// {
|
|
// ii.AmountTotal = ii.AmountPerUnit.Value * ii.UnitCount;
|
|
// ii.GrossAmountTotal = ii.AmountTotal;
|
|
// }
|
|
// totalHours = sip.ApprovedHours.Value;
|
|
// }
|
|
// else
|
|
// {
|
|
// totalHours += ii.UnitCount.Value;
|
|
// }
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private void RenameServiceName(InvoiceItem ii)
|
|
{
|
|
if (ii.ServiceRecord != null)
|
|
{
|
|
if (ii.ServiceRecord.ServiceDescription.ServiceCategory.Name.Contains("Fahrt"))
|
|
{
|
|
ii.ItemDescription = "FLS (Fahrtzeit)";
|
|
if (ii.UnitCount.HasValue)
|
|
{
|
|
ii.UnitCount = Math.Round(ii.UnitCount.Value, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
}
|
|
else if (ii.ServiceRecord.ServiceDescription.ServiceCategory.Name.Contains("FLS"))
|
|
{
|
|
if (ii.ServiceRecord.ServiceDescription.Name.Contains("Sonder"))
|
|
{
|
|
ii.ItemDescription = "FLS Sonderkosten";
|
|
}
|
|
else
|
|
{
|
|
ii.ItemDescription = "FLS";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private IList<InvoiceItem> CreateFahrtkostenItems(List<ServiceRecordDC> serviceRecords)
|
|
{
|
|
Dictionary<String, InvoiceItem> text2Item = new Dictionary<String, InvoiceItem>();
|
|
foreach (var sr in serviceRecords)
|
|
{
|
|
if (sr.DistanceInMeter.HasValue && sr.DistanceInMeter > 0/* && !sr.AlreadyAccounted*/)
|
|
{
|
|
decimal fahrtkosten = 0;
|
|
|
|
String text = sr.ServiceDescription.Name;
|
|
if (text.Contains("Sonder"))
|
|
{
|
|
text = "Sonderkilometer";
|
|
}
|
|
else
|
|
{
|
|
text = "gefahrene km";
|
|
}
|
|
InvoiceItem ii = null;
|
|
|
|
if (text2Item.ContainsKey(text))
|
|
{
|
|
ii = text2Item[text];
|
|
}
|
|
else
|
|
{
|
|
ii = new InvoiceItem();
|
|
text2Item.Add(text, ii);
|
|
|
|
ii.UnitCount = 0;
|
|
ii.ItemDescription = text;
|
|
ii.UnitDescription = text;
|
|
ii.AmountPerUnit = FAHRTKOSTEN;
|
|
ii.ItemPeriodStart = accountingPeriodStart;
|
|
ii.ItemPeriodEnd = accountingPeriodEnd;
|
|
}
|
|
|
|
ii.UnitCount += sr.DistanceInMeter;
|
|
sr.AlreadyAccounted = true;
|
|
}
|
|
}
|
|
|
|
var list = text2Item.Values.ToList();
|
|
foreach (var ii in list)
|
|
{
|
|
if (ii.AmountPerUnit.HasValue && ii.UnitCount.HasValue)
|
|
{
|
|
ii.AmountTotal = Math.Round(ii.AmountPerUnit.Value * ii.UnitCount.Value, 2, MidpointRounding.AwayFromZero);
|
|
ii.GrossAmountTotal = ii.AmountTotal;
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
protected List<InvoiceItem> CreateSonstigeKosten(SupportConceptApprovalPeriod scap, Calculations calc, List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod)
|
|
{
|
|
var iiList = new List<InvoiceItem>();
|
|
foreach (ServiceRecordDC iServiceRecord in serviceRecordsInPeriod)
|
|
{
|
|
if (iServiceRecord.Betrag.HasValue && iServiceRecord.Betrag.Value > 0)
|
|
{
|
|
var invoiceItem = new InvoiceItem();
|
|
invoiceItem.UnitCount = 1;
|
|
invoiceItem.AmountPerUnit = iServiceRecord.Betrag;
|
|
invoiceItem.AmountTotal = invoiceItem.AmountPerUnit;
|
|
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
|
|
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
|
|
invoiceItem.GrossAmountTotal = invoiceItem.AmountPerUnit;
|
|
invoiceItem.ItemDescription = iServiceRecord.Notice;
|
|
if (iServiceRecord.Notice.Length > 100)
|
|
{
|
|
invoiceItem.ItemDescription = iServiceRecord.Notice.Substring(0, 100);
|
|
}
|
|
if (iServiceRecord.ServiceDescription.CategoryName.Contains("Fahrt"))
|
|
{
|
|
invoiceItem.ItemDescription = "Fahrtkostenpauschale";
|
|
}
|
|
invoiceItem.ServiceRecord = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(iServiceRecord.ServiceRecordOid.Value);
|
|
if (scap != null)
|
|
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
|
|
|
|
iiList.Add(invoiceItem);
|
|
}
|
|
}
|
|
|
|
return iiList;
|
|
}
|
|
|
|
public override IList<InvoiceItem> CreateSummaryInvoiceItems(IList<InvoiceItem> itemList,
|
|
DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc, bool summaryPerMonth, bool addRateFactorToUnitCount)
|
|
{
|
|
var newlist = new List<InvoiceItem>();
|
|
|
|
var rateToItem = new Dictionary<String, InvoiceItem>();
|
|
foreach (InvoiceItem iitem in itemList)
|
|
{
|
|
InvoiceItem item;
|
|
|
|
if ((iitem.ItemDescription == "FLS" || iitem.ItemDescription == "FLS Sonderkosten") && organisationRateFactor > 0 && (!iitem.RateFactor.HasValue || iitem.RateFactor.Value == 0))
|
|
{
|
|
iitem.RateFactor = organisationRateFactor;
|
|
}
|
|
String key = String.Format("{0}_{1}_{2}", iitem.AmountPerUnit, iitem.RateFactor, iitem.ItemDescription);
|
|
|
|
if (rateToItem.ContainsKey(key))
|
|
{
|
|
item = rateToItem[key];
|
|
}
|
|
else
|
|
{
|
|
item = new InvoiceItem();
|
|
newlist.Add(item);
|
|
|
|
item.AmountPerUnit = iitem.AmountPerUnit;
|
|
if (invoicePeriod != null)
|
|
{
|
|
item.ItemPeriodStart = invoicePeriod.StartDate;
|
|
item.ItemPeriodEnd = invoicePeriod.EndDate;
|
|
}
|
|
else
|
|
{
|
|
item.ItemPeriodStart = scap.StartDate;
|
|
item.ItemPeriodEnd = scap.EndDate;
|
|
}
|
|
if (summaryPerMonth && iitem.ItemPeriodStart.HasValue)
|
|
{
|
|
DateTime start = new DateTime(iitem.ItemPeriodStart.Value.Year, iitem.ItemPeriodStart.Value.Month, 1);
|
|
DateTime end = start.AddMonths(1).AddDays(-1);
|
|
|
|
if (item.ItemPeriodStart < start)
|
|
{
|
|
item.ItemPeriodStart = start;
|
|
}
|
|
if (item.ItemPeriodEnd > end)
|
|
{
|
|
item.ItemPeriodEnd = end;
|
|
}
|
|
}
|
|
item.RateFactor = iitem.RateFactor;
|
|
|
|
item.AccountingInterval = iitem.AccountingInterval;
|
|
item.ItemDescription = iitem.ItemDescription;
|
|
item.UnitDescription = iitem.UnitDescription;
|
|
item.SupportConceptApprovalPeriodOid = scap.Oid;
|
|
|
|
|
|
rateToItem[key] = item;
|
|
}
|
|
|
|
if (!item.UnitCount.HasValue)
|
|
{
|
|
item.UnitCount = 0;
|
|
}
|
|
item.UnitCount += iitem.UnitCount ?? 0;
|
|
}
|
|
|
|
BerechneSummaryItemsSummen(newlist, true);
|
|
return newlist;
|
|
}
|
|
}
|
|
}
|