diff --git a/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceCreation.cs b/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceCreation.cs new file mode 100644 index 000000000..0c8818304 --- /dev/null +++ b/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceCreation.cs @@ -0,0 +1,156 @@ +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.Invoicing; +using BS.Shared.Core; +using BS.Shared.DataContracts; +using BS.Shared.Extensions; +using BS.Shared.Services; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace LebenshilfeStade.Invoicing +{ + + public class CustomInvoiceCreation : InvoiceCreation + { + public override void SetInvoiceId(ServiceInvoice invoice) + { + base.SetInvoiceId(invoice); + } + + public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc) + { + var invoiceItem = base.CreateInvoiceItem(iServiceRecord, scap, calc); + + // Vermerken, ob MA (un)qualifiziert ist, um den richtigen Preis für die Pauschale zu bekommen (in "Preise" hinterlegt) + //var emp = DAOFactory.GenericDAO.GetByID(iServiceRecord.Employee.EmployeeOid); + //if (emp.IsQualified.HasValue) + // invoiceItem.Notice = emp.IsQualified.Value ? "Wegepauschale Qualifiziert" : "Wegepauschale kompensatorisch"; + + var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods; + if (crp != null && crp.Count > 0) + { + var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit); + var minsProFLS = minutesPerServiceUnit != null ? minutesPerServiceUnit.CostRateValue : 60; + + //invoiceItem.UnitCount = invoiceItem.UnitCount * 60 / minsProFLS; + invoiceItem.GrossAmountTotal = invoiceItem.GrossAmountTotal * 60 / minsProFLS; + invoiceItem.AmountTotal = invoiceItem.AmountTotal * 60 / minsProFLS; + } + + return invoiceItem; + } + + public override IList CreateInvoiceItems(List serviceRecordsInPeriod, DateTimeSpan invoicePeriod, + SupportConceptApprovalPeriod scap, BS.Shared.Services.Calculations calc) + { + var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc); + + var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods; + decimal minsProFLS = 60; + if (crp != null && crp.Count > 0) + { + var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit); + minsProFLS = minutesPerServiceUnit.CostRateValue.Value; + } + + if (scap.CostBearer2SupportConcept.CostBearer.Organisation.Name.ToLower().Contains("neue fls ab 01/2024")) + { + List toAdd = new List(); + foreach (var item in list) + { + item.UnitCount *= 60 / minsProFLS; + + var countQualifiziert = serviceRecordsInPeriod.Where(sr => sr.ServiceDescription.CategoryName.ToLower().Contains("qualifiziert") && sr.ServiceDescription.Name.ToLower().Contains("mit wegezeit")).ToList(); + toAdd.Add(CreateKontaktpauschalenItem(countQualifiziert.Count, item.ItemPeriodStart, item.ItemPeriodEnd, "Wegepauschale Qualifiziert")); + var countKompensatorisch = serviceRecordsInPeriod.Where(sr => sr.ServiceDescription.CategoryName.ToLower().Contains("kompensatorisch") && sr.ServiceDescription.Name.ToLower().Contains("mit wegezeit")).ToList(); + toAdd.Add(CreateKontaktpauschalenItem(countKompensatorisch.Count, item.ItemPeriodStart, item.ItemPeriodEnd, "Wegepauschale kompensatorisch")); + + } + if (toAdd.Count > 0) + list.AddRange(toAdd); + } + + return list; + } + + public override void BerechneSummaryItemsSummen(List newlist, bool addRateFactorToUnitCount) + { + // Rausfinden, ob FLS 50 statt 60 Minuten gehen + // + var oid = newlist.FirstOrDefault(i => i.SupportConceptApprovalPeriodOid != null).SupportConceptApprovalPeriodOid; + SupportConceptApprovalPeriod ap = new SupportConceptApprovalPeriod(); + if (oid != null) + ap = DAOFactory.GenericDAO.GetByID(oid.Value); + + List crp = null; + if (ap != null) + crp = ap.CostBearer2SupportConcept.CostBearer.CostRatePeriods.ToList(); + + if (crp != null && crp.Count > 0) + { + var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit); + var minsProFLS = minutesPerServiceUnit != null ? minutesPerServiceUnit.CostRateValue : 60; + + foreach (InvoiceItem invoiceItem in newlist) + { + if (!invoiceItem.AmountPerUnit.HasValue) + { + invoiceItem.AmountPerUnit = 0; + } + invoiceItem.AmountPerUnit = Math.Round(invoiceItem.AmountPerUnit.Value, 2, MidpointRounding.AwayFromZero); + + if (!invoiceItem.UnitCount.HasValue) + { + invoiceItem.UnitCount = 0; + } + + if (addRateFactorToUnitCount && invoiceItem.RateFactor.HasValue) + { + invoiceItem.UnitCount = (invoiceItem.UnitCount ?? 0) * ((invoiceItem.RateFactor + 100) / 100); + } + + invoiceItem.UnitCount = Math.Round(invoiceItem.UnitCount.Value, 2, MidpointRounding.AwayFromZero); + + + // Änderung: Eine FLS hat 50 statt 60 Minuten + invoiceItem.AmountTotal = invoiceItem.AmountPerUnit * (invoiceItem.UnitCount * 60 / minsProFLS); + invoiceItem.AmountTotal = Math.Round(invoiceItem.AmountTotal.Value, 2, MidpointRounding.AwayFromZero); + + invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal; + + + if (!addRateFactorToUnitCount && invoiceItem.RateFactor.HasValue) + { + invoiceItem.GrossAmountTotal *= (invoiceItem.RateFactor + 100) / 100; + } + } + + } + } + + + private InvoiceItem CreateKontaktpauschalenItem(decimal? unitCount, DateTime? itemPeriodStart, DateTime? itemPeriodEnd, string bezeichnungPreis) + { + var pauschale = GetPreis(bezeichnungPreis, itemPeriodStart.Value); + + var ii = new InvoiceItem() + { + UnitCount = unitCount, + ItemDescription = "Kontaktpauschale", + UnitDescription = "Pauschale pro direktem Kontakt", + AmountPerUnit = pauschale, + AmountTotal = pauschale * unitCount, + GrossAmountTotal = pauschale * unitCount, + ItemPeriodStart = itemPeriodStart, + ItemPeriodEnd = itemPeriodEnd + }; + + + + return ii; + } + + } +} diff --git a/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceFactory.cs b/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceFactory.cs new file mode 100644 index 000000000..7d27fb179 --- /dev/null +++ b/ReportImp/LebenshilfeStade/Invoicing/CustomInvoiceFactory.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using BeWo.Service.Invoicing; +using BS.Shared.DataContracts; +using BS.Shared.DataContracts.Compact; +using BS.Shared.Services; + +namespace LebenshilfeStade.Invoicing +{ + public class CustomInvoiceFactory : InvoiceFactory + { + + public override InvoiceCreation CreateInvoiceCreator(string specificId, string tenant, Dictionary> supportConcepts2ServiceRecords) + { + + foreach (var item in supportConcepts2ServiceRecords) + { + var csc = item.Key; + if (csc.CostBearer.ToLower().Contains("neue fls ab 01/2024")) + { + return new CustomInvoiceCreation(); + } + } + + return new InvoiceCreation(); + } + } +} diff --git a/ReportImp/LebenshilfeStade/Invoicing/CustomSettlementInvoiceCreation.cs b/ReportImp/LebenshilfeStade/Invoicing/CustomSettlementInvoiceCreation.cs new file mode 100644 index 000000000..5f3d51813 --- /dev/null +++ b/ReportImp/LebenshilfeStade/Invoicing/CustomSettlementInvoiceCreation.cs @@ -0,0 +1,135 @@ +using BeWo.Data.Entities; +using BeWo.Service.Invoicing; +using BS.Shared.DataContracts; +using BS.Shared.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LebenshilfeStade.Invoicing +{ + public class CustomSettlementInvoiceCreation : SettlementInvoiceCreation + { + public override bool CanCreateInvoiceTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s) + { + return false; + } + + public override InvoiceItemDC CreateInvoiceItemForAccountingPeriod(AccountingPeriod accountingPeriod) + { + var item = base.CreateInvoiceItemForAccountingPeriod(accountingPeriod); + var mins = accountingPeriod.CostRatesInPeriod.FirstOrDefault(p => p.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit); + + if (mins != null && mins.CostRateValue != null) + { + item.UnitCount *= 60 / mins.CostRateValue; + item.UnitCountBudget *= 60 / mins.CostRateValue; + } + + return item; + } + + public override List CreateInvoiceItemsForAccountingPeriods(Settlement2DC si, List accountingPeriods, + List costRatePeriods, Calculations calc) + { + Dictionary oid2Scap = new Dictionary(); + List invoiceItems = new List(); + + foreach (var ap in accountingPeriods) + { + InvoiceItemDC ii = CreateInvoiceItemForAccountingPeriod(ap); + invoiceItems.Add(ii); + + // ANPASSUNG + if (si.RecipientOrganisation.ToLower().Contains("neue fls ab 01/2024")) + { + InvoiceItemDC pauschalenItem = CreateKontaktpauschalenItem(ap, si.RecipientOrganisation); + if (pauschalenItem != null) + invoiceItems.Add(pauschalenItem); + } + + + var scap = ap.SupportConceptApprovalPeriod; + SupportConceptApprovalPeriodDC scapHelper = null; + + if (scap != null) + { + if (oid2Scap.ContainsKey(scap.SupportConceptApprovalPeriodOid.Value)) + scapHelper = oid2Scap[scap.SupportConceptApprovalPeriodOid.Value]; + else + { + scapHelper = new SupportConceptApprovalPeriodDC(); + scapHelper.ApprovedBETotal = scap.ApprovedBETotal; + if (!scapHelper.ApprovedBETotal.HasValue) + scapHelper.ApprovedBETotal = calc.GetApprovedBETotal(scap, costRatePeriods); + + oid2Scap[scap.SupportConceptApprovalPeriodOid.Value] = scapHelper; + } + } + + if (!si.ApprovedFLS.HasValue) + { + if (scapHelper.ApprovedBETotal.HasValue && ii.UnitCount.HasValue) + { + if (scapHelper.ApprovedBETotal >= ii.UnitCount.Value) + { + scapHelper.ApprovedBETotal -= ii.UnitCount.Value; + ii.MaxApprovedUnitCount = null; + } + else + { + ii.MaxApprovedUnitCount = scapHelper.ApprovedBETotal; + } + } + + CalculateInvoiceItemAmounts(ii); + } + + if (ii.UnitCount.HasValue) + { + si.RecordedBillableFLSBrutto = (si.RecordedBillableFLSBrutto ?? 0) + ii.UnitCount; + si.RecordedBillableFLSNetto = si.RecordedBillableFLSBrutto ?? 0; + } + + var list = CreateAdditionalInvoiceItems(ap); + invoiceItems.AddRange(list); + } + return invoiceItems; + } + + private static InvoiceItemDC CreateKontaktpauschalenItem(AccountingPeriod accountingPeriod, string recipientOrganisation) + { + InvoiceItemDC invoiceItem = null; + decimal unitCount = 0; + + foreach (var sr in accountingPeriod.ServiceRecordsInPeriod) + { + if (sr.ServiceDescription.Name.ToLower().Contains("face to face") || sr.ServiceDescription.Name.ToLower().Contains("face to face")) + { + unitCount++; + } + } + + if (unitCount > 0) + { + decimal pauschale = PauschalenHelper.PAUSCHALE; + + invoiceItem = new InvoiceItemDC() + { + UnitCount = unitCount, + ItemDescription = "Kontaktpauschale", + UnitDescription = "Pauschale pro direktem Kontakt", + AmountPerUnit = pauschale, + AmountTotal = pauschale * unitCount, + GrossAmountTotal = pauschale * unitCount * accountingPeriod.RateFactor, + ItemPeriodStart = accountingPeriod.PeriodStart, + ItemPeriodEnd = accountingPeriod.PeriodEnd, + }; + } + + return invoiceItem; + } + } +} diff --git a/ReportImp/LebenshilfeStade/Invoicing/PauschalenHelper.cs b/ReportImp/LebenshilfeStade/Invoicing/PauschalenHelper.cs new file mode 100644 index 000000000..e91cf0ec2 --- /dev/null +++ b/ReportImp/LebenshilfeStade/Invoicing/PauschalenHelper.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LebenshilfeStade.Invoicing +{ + public class PauschalenHelper + { + public const decimal PAUSCHALE = 14.57m; + } +} diff --git a/ReportImp/LebenshilfeStade/LebenshilfeStade.csproj b/ReportImp/LebenshilfeStade/LebenshilfeStade.csproj index f48ba0db4..77a9feec9 100644 --- a/ReportImp/LebenshilfeStade/LebenshilfeStade.csproj +++ b/ReportImp/LebenshilfeStade/LebenshilfeStade.csproj @@ -86,6 +86,10 @@ InvoiceCustomerReport.cs + + + + Component @@ -206,6 +210,7 @@ +