MH: Rundung input Familienhilfe

This commit is contained in:
2023-02-10 10:01:01 +01:00
parent 845719d3b5
commit 0e80ae2499
2 changed files with 369 additions and 0 deletions

View File

@@ -63,6 +63,7 @@
<Compile Include="InvoiceCustomerReport.Designer.cs">
<DependentUpon>InvoiceCustomerReport.cs</DependentUpon>
</Compile>
<Compile Include="Invoicing\CustomSettlementInvoiceCreation.cs" />
<Compile Include="Invoicing\SgaInvoiceCreation.cs" />
<Compile Include="Invoicing\UnterbringungInvoiceCreation.cs" />
<Compile Include="Invoicing\IonInvoiceCreation.cs" />

View File

@@ -0,0 +1,368 @@
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.Extensions;
using BS.Shared.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InputFamilienhilfe.Invoicing
{
class CustomSettlementInvoiceCreation : SettlementInvoiceCreation
{
public override void CreateInvoiceDetailsTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s)
{
bool isLWL = false;
String id = c2s.CostBearer.ID;
if (String.IsNullOrEmpty(id))
{
if (!String.IsNullOrEmpty(si.RecipientOrganisation) && si.RecipientOrganisation.Trim().ToLower().IndexOf("lwl") == 0)
{
isLWL = true;
id = "LWL";
}
}
var calc = PluginLoader.FindClass<Calculations>(id) ?? Calculations.GetInstance(id);
var relDC = c2s.MapToNewDC();
decimal lDurationInWeeks =
calc.GetIntervalCountForDays(
Convert.ToDecimal((c2s.EndDate.Value - c2s.StartDate.Value).Days + 1),
SupportConceptApprovalInterval.Weekly);
decimal lApprovedFLSWeeklyForMaxAmountCalculation = 0;
CalculateSettlementInvoiceApprovedAmounts(si, relDC, calc);
DateTime periodStart = si.AccountingPeriodStart.Value.Date;
DateTime periodEnd = si.AccountingPeriodEnd.Value.Date;
//Prüfe ob vorher abgemeldet
if (c2s.SupportConcept.Customer.TerminationDate.HasValue &&
c2s.SupportConcept.Customer.TerminationDate.Value < periodEnd)
{
periodEnd = c2s.SupportConcept.Customer.TerminationDate.Value;
si.ErrorNotice =
String.Format(
"Achtung: Die Betreuung endete am {0:dd.MM.yyyy}. Alle nachträglich eingegebenen Stunden werden nicht abgerechnet!",
periodEnd);
}
//Prüfe ob Enddatum in Zukunft liegt:
if (periodEnd > DateTime.Now)
{
var srList = c2s.ServiceRecords;
var max = srList.Max(s => s.End);
if (max.HasValue && max < periodEnd)
{
periodEnd = max.Value;
}
}
var tolerancesInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.ServiceTolerance, periodStart, periodEnd).ToList();
var hourlyRatesInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.HourlyRate, periodStart, periodEnd).ToList();
si.DifferentHourlyRateCount = hourlyRatesInSpanList.Count;
if (hourlyRatesInSpanList.Count > 1)
{
if (hourlyRatesInSpanList.Count == 2)
{
si.WeeksWithOldHourlyRate =
calc.GetIntervalCountForDays(Convert.ToDecimal(hourlyRatesInSpanList.First().Value.GetTimeSpan().Days + 1),
SupportConceptApprovalInterval.Weekly);
si.WeeksWithNewHourlyRate =
calc.GetIntervalCountForDays(
Convert.ToDecimal((c2s.EndDate.Value - hourlyRatesInSpanList.Last().Value.StartDate).Days + 1),
SupportConceptApprovalInterval.Weekly);
si.WeeksWithHourlyRate3 = 0;
}
else if (hourlyRatesInSpanList.Count == 3)
{
si.WeeksWithHourlyRate3 =
calc.GetIntervalCountForDays(Convert.ToDecimal(hourlyRatesInSpanList.First().Value.GetTimeSpan().Days + 1),
SupportConceptApprovalInterval.Weekly);
si.WeeksWithOldHourlyRate =
calc.GetIntervalCountForDays(Convert.ToDecimal(hourlyRatesInSpanList.ElementAt(1).Value.GetTimeSpan().Days + 1),
SupportConceptApprovalInterval.Weekly);
si.WeeksWithNewHourlyRate =
calc.GetIntervalCountForDays(
Convert.ToDecimal((c2s.EndDate.Value - hourlyRatesInSpanList.Last().Value.StartDate).Days + 1),
SupportConceptApprovalInterval.Weekly);
}
}
else
{
si.WeeksWithNewHourlyRate = lDurationInWeeks;
}
decimal currentRateFactor = 0;
decimal currentHourlyRate = 0;
decimal lastHourlyRate = 0;
decimal thirdHourlyRate = 0;
var rateFactorsInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor, periodStart, periodEnd).ToList();
if (hourlyRatesInSpanList.Count > 0)
{
var cdc = hourlyRatesInSpanList.Last().Key;
if (cdc.CostRateValue.HasValue)
currentHourlyRate = cdc.CostRateValue.Value;
}
if (rateFactorsInSpanList.Count > 0)
{
var cdc = rateFactorsInSpanList.Last().Key;
if (cdc.CostRateValue.HasValue)
currentRateFactor = cdc.CostRateValue.Value;
}
if (hourlyRatesInSpanList.Count > 1)
{
var cdc = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 2].Key;
if (cdc.CostRateValue.HasValue)
lastHourlyRate = cdc.CostRateValue.Value;
si.HourlyRateOldEndDate = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 2].Value.EndDate;
si.HourlyRateNewStartDate = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 1].Value.StartDate;
}
if (hourlyRatesInSpanList.Count > 2)
{
var cdc = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 3].Key;
if (cdc.CostRateValue.HasValue)
thirdHourlyRate = cdc.CostRateValue.Value;
si.HourlyRateEndDate3 = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 3].Value.EndDate;
si.HourlyRateOldStartDate = hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 2].Value.StartDate;
}
if (si.ApprovedFLSWeekly == null)
{
si.ApprovedFLSWeekly = 0;
}
//decimal maxAmount = 0;
//decimal maxFLS = lApprovedFLSWeeklyForMaxAmountCalculation * si.WeeksWithNewHourlyRate;
//maxFLS += lApprovedFLSWeeklyForMaxAmountCalculation * si.WeeksWithOldHourlyRate;
//maxFLS += lApprovedFLSWeeklyForMaxAmountCalculation * si.WeeksWithHourlyRate3;
si.RateFactor = currentRateFactor;
si.HourlyRateNew = currentHourlyRate;
si.HourlyRateOld = lastHourlyRate;
si.HourlyRate3 = thirdHourlyRate;
//decimal totalAmount = 0;
var records = GetBillableServiceRecords(c2s);
records =
records.Where(i => i.Start.HasValue && i.Start.Value.InBetween(periodStart, periodEnd, true)).ToList();
var recordDCS = records.MapToNewDCs();
var absenceTimes = MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(c2s.SupportConcept.Customer.AbsenceTimes);
Dictionary<DateTimeSpan, decimal> span2Hours = calc.GetAbsencesTimesNotBillable(absenceTimes);
si.RecordedBillableFLSNotBillableCustomerAbsent
= calc.GetHoursNotBillableDueToAbsenceTimes(relDC, recordDCS,
span2Hours, false, false);
si.RecordedBillableFLSNotBillableOutOfApprovedSpan = calc.GetHoursNotBillableDueToOutOfSpan(relDC, recordDCS);
//calc.GetHoursNotBillableDueToMoreThanApproved(relDC, recordDCS, false, false);
Dictionary<long, bool> groupBookingDict = new Dictionary<long, bool>();
decimal flsCleared = 0;
records =
records.OrderBy<ServiceRecord, DateTime>(sr => sr.Start.HasValue ? sr.Start.Value : DateTime.MinValue)
.ToList<ServiceRecord>();
decimal tolerance = 100;
if (tolerancesInSpanList.Count > 0)
{
if (tolerancesInSpanList[0].Key.CostRateValue.HasValue && tolerancesInSpanList[0].Key.CostRateValue.Value > 0)
{
tolerance = tolerancesInSpanList[0].Key.CostRateValue ?? 100;
}
}
decimal approved = si.ApprovedFLS ?? 0;
if (tolerance != 100)
{
approved = (approved * tolerance) / 100m;
}
if (!CheckMaxApprovedHours())
{
approved = Decimal.MaxValue;
}
foreach (var iRecord in records)
{
if (iRecord.ServiceDescription.ServiceCategory.IsBillable && IsServiceRecordBillable(iRecord))
{
if (iRecord.GroupOid == null || !groupBookingDict.ContainsKey(iRecord.GroupOid.Value))
{
//
if (iRecord.GroupPersonCount != null || iRecord.GroupPersonCount > 0)
iRecord.RoundedDuration = iRecord.GroupRoundedDuration.Value / iRecord.GroupPersonCount.Value;
decimal rd = iRecord.RoundedDuration;
var prozent = iRecord.ServiceDescription.ServiceCategory.ProzentAbrechnung;
if (iRecord.ServiceDescription.ProzentAbrechnung.HasValue)
{
prozent = iRecord.ServiceDescription.ProzentAbrechnung.Value;
}
rd = (rd * prozent) / 100;
decimal duration = rd / 60;
if (si.RecordedBillableFLSBrutto == null)
{
si.RecordedBillableFLSBrutto = 0;
}
si.RecordedBillableFLSBrutto += duration;
si.RecordedBillableFLSNetto += duration;
//if (maxAmount == 0)
//{
if (flsCleared + duration > approved)
{
duration = approved - flsCleared;
flsCleared = approved;
}
else
{
flsCleared += duration;
}
//}
//decimal? hourlyRate = null;
//decimal? rateFactor = null;
var rates = c2s.CostBearer.CostRatePeriods.MapToNewDCs();
//if (iRecord.Start != null)
//{
// hourlyRate = rates.GetValidRateValueForDate(CostRatePeriodType.HourlyRate, iRecord.Start.Value);
// rateFactor = rates.GetValidRateValueForDate(CostRatePeriodType.RateFactor, iRecord.Start.Value);
//}
//else
//{
// hourlyRate = rates.GetCurrentlyValidRateValue(CostRatePeriodType.HourlyRate);
// rateFactor = rates.GetCurrentlyValidRateValue(CostRatePeriodType.RateFactor);
//}
//if (!hourlyRate.HasValue)
// hourlyRate = 0;
//if (!rateFactor.HasValue)
// rateFactor = 0;
if (hourlyRatesInSpanList.Count > 2 && iRecord.Start != null &&
iRecord.Start < hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 2].Value.StartDateTime)
{
si.ApprovedFLSWithHourlyRate3 += duration;
}
else if (hourlyRatesInSpanList.Count > 1 && iRecord.Start != null &&
iRecord.Start < hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 1].Value.StartDateTime)
{
si.ApprovedFLSWithOldHourlyRate += duration;
}
else
{
si.ApprovedFLSWithActualHourlyRate += duration;
}
if (iRecord.GroupOid != null && !groupBookingDict.ContainsKey(iRecord.GroupOid.Value))
{
si.HasGroupRecords = true;
groupBookingDict.Add(iRecord.GroupOid.Value, true);
}
}
}
}
si.ApprovedFLSWithActualHourlyRate = Math.Round(si.ApprovedFLSWithActualHourlyRate, 2, MidpointRounding.AwayFromZero);
si.ApprovedFLSWithHourlyRate3 = Math.Round(si.ApprovedFLSWithHourlyRate3, 2, MidpointRounding.AwayFromZero);
si.ApprovedFLSWithOldHourlyRate = Math.Round(si.ApprovedFLSWithOldHourlyRate, 2, MidpointRounding.AwayFromZero);
decimal rf = 1;
if (si.RateFactor.HasValue && si.RateFactor.Value != 0)
{
rf = si.RateFactor.Value;
rf = (100 + rf) / 100;
}
decimal roundedNewAmount = 0;
decimal amountRateFactor = 0;
if (si.HourlyRateNew.HasValue)
{
roundedNewAmount = Math.Round(si.ApprovedFLSWithActualHourlyRate * si.HourlyRateNew.Value * rf, 2,
MidpointRounding.AwayFromZero);
amountRateFactor =
Math.Round(
roundedNewAmount -
Math.Round(si.ApprovedFLSWithActualHourlyRate * si.HourlyRateNew.Value, 2, MidpointRounding.AwayFromZero), 2,
MidpointRounding.AwayFromZero);
}
if (si.HourlyRateOld.HasValue)
{
decimal a2 = Math.Round(si.ApprovedFLSWithOldHourlyRate * si.HourlyRateOld.Value * rf, 2, MidpointRounding.AwayFromZero);
roundedNewAmount += a2;
amountRateFactor +=
Math.Round(
a2 - Math.Round(si.ApprovedFLSWithOldHourlyRate * si.HourlyRateOld.Value, 2, MidpointRounding.AwayFromZero), 2,
MidpointRounding.AwayFromZero);
}
if (si.HourlyRate3 > 0)
{
decimal a3 = Math.Round(si.ApprovedFLSWithHourlyRate3 * si.HourlyRate3 * rf, 2, MidpointRounding.AwayFromZero);
roundedNewAmount += a3;
amountRateFactor +=
Math.Round(a3 - Math.Round(si.ApprovedFLSWithHourlyRate3 * si.HourlyRate3, 2, MidpointRounding.AwayFromZero), 2,
MidpointRounding.AwayFromZero);
}
si.AmountWithRateFactor += amountRateFactor;
var totalAmount = Math.Round(roundedNewAmount, 2, MidpointRounding.AwayFromZero);
decimal? maxAmount = CalculateMaxAmount(si);
if (maxAmount.HasValue && totalAmount > maxAmount.Value)
{
totalAmount = maxAmount.Value;
}
si.AmountBillableTotal = totalAmount;
//AdvancedPayments
CalculateAdvancedPayments(si, c2s, null, null, hourlyRatesInSpanList);
//EquityContribution (Eigenanteil)
CalculateEquityContribution(si, c2s.SupportConcept, null, null);
si.Claim = si.AmountBillableTotal - (si.AmountAdvancedPayments ?? 0) - si.EquityContribution;
}
}
}