MH: Rundung input Familienhilfe
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user