Files
BeWoPlaner/ReportImp/InputFamilienhilfe/Invoicing/DefaultInvoiceCreation.cs

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;
}
}
}