MH: Team Pfeil Korridore in der Abrechnung finale Version
SupportOID=167413
This commit is contained in:
@@ -179,7 +179,7 @@ namespace TeamPfeil
|
||||
if (ap.ServiceCategory.Name.Contains("Qualifizierte Assistenz"))
|
||||
{
|
||||
budgetFuerQualAss = KorridorberechnungHelper.BerechneBudgetFuerQualAss(bewilligtGesamt);
|
||||
double genutzt = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(scOid, ap.ServiceCategory, budgetFuerQualAss, ro.EndDate, true);
|
||||
double genutzt = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(scOid, ap.ServiceCategory, budgetFuerQualAss, ro.EndDate.AddDays(1).AddTicks(-1), true);
|
||||
|
||||
ro.TotalFLMQualified = genutzt;
|
||||
ro.TotalFLSQualified = budgetFuerQualAss - genutzt;
|
||||
@@ -194,7 +194,7 @@ namespace TeamPfeil
|
||||
else if (ap.ServiceCategory.Name.Contains("Unterstützende Assistenz"))
|
||||
{
|
||||
budgetFuerUnterstAss = KorridorberechnungHelper.BerechneBudgetFuerUnterstAss(bewilligtGesamt);
|
||||
double genutzt = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(scOid, ap.ServiceCategory, budgetFuerUnterstAss, ro.EndDate, false);
|
||||
double genutzt = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(scOid, ap.ServiceCategory, budgetFuerUnterstAss, ro.EndDate.AddDays(1).AddTicks(-1), false);
|
||||
|
||||
ro.TotalFLMUnqualified = genutzt;
|
||||
ro.TotalFLSUnqualified = budgetFuerUnterstAss - genutzt;
|
||||
|
||||
@@ -69,7 +69,57 @@ namespace TeamPfeil.Invoicing
|
||||
}
|
||||
}
|
||||
|
||||
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc)
|
||||
{
|
||||
var list = new List<InvoiceItem>();
|
||||
foreach (ServiceRecordDC iServiceRecord in serviceRecordsInPeriod)
|
||||
{
|
||||
if (iServiceRecord.ServiceDescription.Category.IsBillable)
|
||||
{
|
||||
if (!iServiceRecord.AlreadyAccounted)
|
||||
{
|
||||
InvoiceItem invoiceItem = CreateInvoiceItem(iServiceRecord, scap, calc);
|
||||
if (invoiceItem != null)
|
||||
{
|
||||
// Wenn das Item ganz normal abgerechnet wird, einfach normal zur Liste
|
||||
if (invoiceItem.CustomString5 != "Mischitem")
|
||||
list.Add(invoiceItem);
|
||||
else
|
||||
{
|
||||
// Ist es ein Mischitem, müssen zwei Items erstellt werden. Eins mit dem Mitarbeiterstundensatz und eins mit dem Leistungsstundensatz
|
||||
// invoiceItem.CustomNumber1: Stunden für den MA-Stundensatz
|
||||
// invoiceItem.CustomNumber2: MA-Stundensatz
|
||||
// invoiceItem.CustomString2: Leistungsname für MA-Stundensatz
|
||||
// invoiceItem.CustomNumber3: Stunden für den Leistungs-Stundensatz
|
||||
// invoiceItem.CustomNumber4: Leistungs-Stundensatz
|
||||
// invoiceItem.CustomString4: Leistungsname für Leistungsstundensatz
|
||||
var item1 = invoiceItem;
|
||||
var item2 = CopyInvoiceItem(invoiceItem);
|
||||
|
||||
item1.UnitCount = invoiceItem.CustomNumber1;
|
||||
item1.AmountPerUnit = invoiceItem.CustomNumber2;
|
||||
item1.AmountTotal = item1.UnitCount * invoiceItem.AmountPerUnit;
|
||||
item1.GrossAmountTotal = item1.AmountTotal;
|
||||
item1.ItemDescription = item1.CustomString2;
|
||||
list.Add(item1);
|
||||
|
||||
item2.UnitCount = invoiceItem.CustomNumber3;
|
||||
item2.AmountPerUnit = invoiceItem.CustomNumber4;
|
||||
item2.AmountTotal = item2.UnitCount * invoiceItem.AmountPerUnit;
|
||||
item2.GrossAmountTotal = item2.AmountTotal;
|
||||
item2.ItemDescription = item1.CustomString4;
|
||||
list.Add(item2);
|
||||
}
|
||||
}
|
||||
iServiceRecord.AlreadyAccounted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CreateSummaryInvoiceItems(list, invoicePeriod, scap, calc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
|
||||
{
|
||||
@@ -111,6 +161,7 @@ namespace TeamPfeil.Invoicing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Ab 2026 wird das abgerechnet, was dokumentiert wird.
|
||||
// Sonderfall: Korridor
|
||||
// Korridor wird Thema, wenn die bewilligte Leistungsform sich von der Qualifikation der dokumentierenden Person unterscheidet.
|
||||
@@ -121,81 +172,100 @@ namespace TeamPfeil.Invoicing
|
||||
// den der Korridormitarbeiter eigentlich hat (also qualfi.abhäng. Stundensatz im Kostenträger, der der Qualifikation des Mitarbeiters entspricht)
|
||||
else
|
||||
{
|
||||
bool korridorAufgebraucht = false;
|
||||
bool mischitem = false; // Mischitem = ServiceRecord kann nur teilweise mit Leistungsstundensatz abgerechnet werden, teils aber mit MA-Qual--Std.satz
|
||||
|
||||
bool korridorAufgebraucht = false; // Wenn true, wird statt dem Leistungsstundensatz der MA-Stundensatz genommen
|
||||
// Mischitem = ServiceRecord kann nur teilweise mit Leistungsstundensatz abgerechnet werden, der Rest muss aber mit MA-Qual--Std.satz abgerechnet werden
|
||||
// In dem Fall werden im Item beide Teilstunden und beide jeweiligem Stundensätze gesetzt und im Nachgang wird ein weiteres Item erzeugt (in CreateInvoiceItems)
|
||||
bool mischitem = false;
|
||||
|
||||
// KORRIDOR ERMITTELN
|
||||
var scapDC = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(scap);
|
||||
var gesamtBewilligt = KorridorberechnungHelper.BerechneStundenBewilligtGesamt(scapDC);
|
||||
double korridorbudget = 0;
|
||||
double genutztesKorridorbudget = 0;
|
||||
double rest = 0;
|
||||
|
||||
if (scap.ServiceCategory.Name.Contains("Qualifizierte Assistenz"))
|
||||
{
|
||||
korridorbudget = KorridorberechnungHelper.BerechneBudgetFuerQualAss(gesamtBewilligt);
|
||||
genutztesKorridorbudget = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(iServiceRecord.SupportConcept.SupportConceptOid, scapDC.ServiceCategory,
|
||||
korridorbudget, iServiceRecord.Start.Value, true);
|
||||
korridorbudget, iServiceRecord.Start.Value.AddTicks(-1), true);
|
||||
rest = korridorbudget - genutztesKorridorbudget;
|
||||
}
|
||||
else if (scap.ServiceCategory.Name.Contains("Unterstützende Assistenz"))
|
||||
{
|
||||
korridorbudget = KorridorberechnungHelper.BerechneBudgetFuerUnterstAss(gesamtBewilligt);
|
||||
genutztesKorridorbudget = KorridorberechnungHelper.BerechneGenutzteKorridorstunden(iServiceRecord.SupportConcept.SupportConceptOid, scapDC.ServiceCategory,
|
||||
korridorbudget, iServiceRecord.Start.Value, false);
|
||||
korridorbudget, iServiceRecord.Start.Value.AddTicks(-1), false);
|
||||
rest = korridorbudget - genutztesKorridorbudget;
|
||||
}
|
||||
|
||||
// todo: Wenn das Item noch etwas Restbudget hat, aber es nicht ganz ausreicht, um alles abzudecken, muss eig ein Mischitem erzeugt werden.
|
||||
// Wenn das Item noch etwas Restbudget hat, aber es nicht ganz ausreicht, um alles abzudecken, muss ein Mischitem erzeugt werden.
|
||||
// Es muss also der Teil, der noch verfügbar ist, mit dem Leistungsstundensatz verrechnet werden und der Rest mit der Qualifikation
|
||||
// Dazu werden der jeweilige UnitCount und der jeweilige Stundensatz in CustomNumbers gespeichert, um in CreateInvoiceItems ein zweites Item zu machen
|
||||
if (rest > 0 && rest - Convert.ToDouble(iServiceRecord.RoundedDuration) / 60 < 0)
|
||||
{
|
||||
decimal zeitNormalAbrechenbar = Convert.ToDecimal(rest);
|
||||
decimal zeitMitMitarbeiterStundensatz = iServiceRecord.RoundedDuration / 60 - Convert.ToDecimal(rest);
|
||||
|
||||
|
||||
// Wenn Mischitem, dann UnitCounts zwischenspeichern, um später aufzuteilen
|
||||
invoiceItem.CustomNumber1 = zeitMitMitarbeiterStundensatz;
|
||||
invoiceItem.CustomNumber3 = zeitNormalAbrechenbar;
|
||||
|
||||
mischitem = true;
|
||||
invoiceItem.CustomString5 = "Mischitem";
|
||||
}
|
||||
else if (rest <= 0)
|
||||
// Wenn der Rest eh schon unter 0 ist, wird einfach mit dem MA-Stundensatz abgerechnet
|
||||
else if (rest < 0)
|
||||
korridorAufgebraucht = true;
|
||||
|
||||
if (korridorAufgebraucht) // Stundensatz der Mitarbeitendenqualifikation
|
||||
if (korridorAufgebraucht || mischitem) // Stundensatz der Mitarbeitendenqualifikation
|
||||
{
|
||||
var qualifikation = iServiceRecord.Employee.ValueListEntries.FirstOrDefault(v => v.Value == ValueListEntryType.StaffQualificationsType);
|
||||
if (qualifikation.Key != null)
|
||||
{
|
||||
qualiOid = qualifikation.Key;
|
||||
if (qualiOid == 2118)
|
||||
if (qualiOid == 2118) // QA 1
|
||||
{
|
||||
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
|
||||
invoiceItem.ItemDescription = "Qualifikationsniveau 1: ";
|
||||
invoiceItem.ItemDescription = "QA 1: ";
|
||||
}
|
||||
else if (qualiOid == 2119)
|
||||
else if (qualiOid == 2119) // QA 2
|
||||
{
|
||||
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
|
||||
invoiceItem.ItemDescription = "Qualifikationsniveau 2: ";
|
||||
invoiceItem.ItemDescription = "QA 2: ";
|
||||
}
|
||||
else if (qualiOid == 2120)
|
||||
else if (qualiOid == 2120) // UA 3
|
||||
{
|
||||
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
|
||||
invoiceItem.ItemDescription = "Qualifikationsniveau 3: ";
|
||||
invoiceItem.ItemDescription = "UA 3: ";
|
||||
}
|
||||
else if (qualiOid == 2121)
|
||||
else if (qualiOid == 2121) // UA 4
|
||||
{
|
||||
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
|
||||
invoiceItem.ItemDescription = "Qualifikationsniveau 4: ";
|
||||
invoiceItem.ItemDescription = "UA 4: ";
|
||||
}
|
||||
|
||||
if (mischitem) // Wenn Mischitem, dann Stundensatz der Person + dessen Qualifikation zwischenspeichern, um später aufzuteilen
|
||||
{
|
||||
invoiceItem.CustomNumber2 = stundensatz;
|
||||
invoiceItem.CustomString2 = invoiceItem.ItemDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Stundensatz, der der dokumentierten Leistung entspricht
|
||||
if (!korridorAufgebraucht || mischitem) // Stundensatz, der der dokumentierten Leistung entspricht
|
||||
{
|
||||
var leistung = iServiceRecord.ServiceDescription.Name;
|
||||
switch (leistung)
|
||||
{
|
||||
case "QA 1": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2118, iServiceRecord.Start); invoiceItem.ItemDescription = "Qualifikationsniveau 1: "; break;
|
||||
case "QA 2": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2119, iServiceRecord.Start); invoiceItem.ItemDescription = "Qualifikationsniveau 2: "; break;
|
||||
case "UA 3": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2120, iServiceRecord.Start); invoiceItem.ItemDescription = "Qualifikationsniveau 3: "; break;
|
||||
case "UA 4": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2121, iServiceRecord.Start); invoiceItem.ItemDescription = "Qualifikationsniveau 4: "; break;
|
||||
case "QA 1": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2118, iServiceRecord.Start); invoiceItem.ItemDescription = "QA 1: "; break;
|
||||
case "QA 2": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2119, iServiceRecord.Start); invoiceItem.ItemDescription = "QA 2: "; break;
|
||||
case "UA 3": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2120, iServiceRecord.Start); invoiceItem.ItemDescription = "UA 3: "; break;
|
||||
case "UA 4": stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, 2121, iServiceRecord.Start); invoiceItem.ItemDescription = "UA 4: "; break;
|
||||
}
|
||||
if (mischitem) // Wenn Mischitem, dann Stundensatz der Leistung + Leistungsbezeichnung zwischenspeichern, um später aufzuteilen
|
||||
{
|
||||
invoiceItem.CustomNumber4 = stundensatz;
|
||||
invoiceItem.CustomString4 = invoiceItem.ItemDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +291,6 @@ namespace TeamPfeil.Invoicing
|
||||
invoiceItem.ItemPeriodEnd = bd.BillingPeriodEnd;
|
||||
invoiceItem.RateFactor = bd.RateFactor;
|
||||
invoiceItem.AccountingInterval = bd.AccountingInterval;
|
||||
//iServiceRecord.Employee + " - " + iServiceRecord.ServiceDescription.Name;
|
||||
invoiceItem.ServiceRecord = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(iServiceRecord.ServiceRecordOid.Value);
|
||||
|
||||
return invoiceItem;
|
||||
@@ -249,7 +318,29 @@ namespace TeamPfeil.Invoicing
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private InvoiceItem CopyInvoiceItem(InvoiceItem invoiceItem)
|
||||
{
|
||||
return new InvoiceItem()
|
||||
{
|
||||
AccountingInterval = invoiceItem.AccountingInterval,
|
||||
AmountPerUnit = invoiceItem.AmountPerUnit,
|
||||
AmountTotal = invoiceItem.AmountTotal,
|
||||
ApprovalUnit = invoiceItem.ApprovalUnit,
|
||||
ApprovedPerUnit = invoiceItem.ApprovedPerUnit,
|
||||
GrossAmountTotal = invoiceItem.GrossAmountTotal,
|
||||
ItemDescription = invoiceItem.ItemDescription,
|
||||
IsActive = invoiceItem.IsActive,
|
||||
ItemPeriodEnd = invoiceItem.ItemPeriodEnd,
|
||||
ItemPeriodStart = invoiceItem.ItemPeriodStart,
|
||||
MaxApprovedAmount = invoiceItem.MaxApprovedAmount,
|
||||
MaxApprovedUnitCount = invoiceItem.MaxApprovedAmount,
|
||||
RateFactor = invoiceItem.RateFactor,
|
||||
ServiceRecord = invoiceItem.ServiceRecord,
|
||||
SupportConceptApprovalPeriodOid = invoiceItem.SupportConceptApprovalPeriodOid,
|
||||
UnitCount = invoiceItem.UnitCount,
|
||||
UnitDescription = invoiceItem.UnitDescription,
|
||||
};
|
||||
}
|
||||
public override string GetSummaryItemKey(SupportConceptApprovalPeriod scap, InvoiceItem iitem, bool summaryPerMonth)
|
||||
{
|
||||
String key = String.Format("{0}_{1}", iitem.AmountPerUnit, iitem.ItemDescription);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace TeamPfeil.Korridorberechnung
|
||||
double genutzteStunden = 0;
|
||||
|
||||
var serviceRecords = DAOFactory.SearchDAO.FindServiceRecordsForSupportConcept(supportConceptOid.Value)
|
||||
.Where(sr => sr.ServiceDescription.ServiceCategory.Oid == serviceCategory.ServiceCategoryOid && sr.Start.Value.Date <= reportEndDate)
|
||||
.Where(sr => sr.ServiceDescription.ServiceCategory.Oid == serviceCategory.ServiceCategoryOid && sr.Start.Value <= reportEndDate)
|
||||
.ToList();
|
||||
|
||||
if (serviceRecords != null && serviceRecords.Count > 0)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using BeWo.Service.Plugins;
|
||||
using BS.Shared.DataContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TeamPfeil.Statistics
|
||||
{
|
||||
public class CustomServiceRecordStatisticFactory : ServiceRecordStatisticFactory
|
||||
{
|
||||
public override SupportConceptStatisticsDC CreateSupportConceptStatisticsImpl(long costBearer2SupportConceptOid, DateTime statisticsDate, long? ignoreServiceRecordOid)
|
||||
{
|
||||
var stats = base.CreateSupportConceptStatisticsImpl(costBearer2SupportConceptOid, statisticsDate, ignoreServiceRecordOid);
|
||||
|
||||
stats.PeriodStatistics = stats.PeriodStatistics.OrderByDescending(s => s.SupportConceptApprovalPeriod.StartDate).ToList();
|
||||
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,7 @@
|
||||
<Compile Include="SettlementReport.Designer.cs">
|
||||
<DependentUpon>SettlementReport.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Statistics\CustomServiceRecordStatisticFactory.cs" />
|
||||
<Compile Include="Validation\ServiceRecordValidator.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user