Files
BeWoPlaner/Shared/Services/LWLCalculations.cs
Christian a896a7bfec cb
2019-09-17 17:44:57 +02:00

234 lines
9.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
namespace BS.Shared.Services
{
// LWL: keinen RateFactor einrechnen
[IDSpecificClass(Identifiers = new string[] { "LWL", "LWLMaxAmount", "LWLNEU", "LWLBeWo67" })]
public class LWLCalculations : Calculations
{
public override decimal GetIntervalCountForDays(decimal totalDays, SupportConceptApprovalInterval interval)
{
return Math.Round(ConvertPerIntervall2PerDay(totalDays, interval), 2, MidpointRounding.AwayFromZero);
}
public override decimal ConvertPerIntervall2PerDay(decimal pPerInterval, SupportConceptApprovalInterval pInterval)
{
decimal val = 0;
if (pInterval == SupportConceptApprovalInterval.Weekly)
val = pPerInterval * .1427m;
else
val = base.ConvertPerIntervall2PerDay(pPerInterval, pInterval);
return val;
}
public override decimal? GetApprovedHoursPerDay(SupportConceptApprovalPeriodDC scap,
List<CostRatePeriodDC> costRatePeriods)
{
if (scap.EndDate.HasValue && scap.StartDate.HasValue && scap.ApprovedBEPerInterval.HasValue && !scap.ApprovedBETotal.HasValue
&& scap.ApprovedBEInterval.HasValue && scap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Weekly)
{
var scapDurationInDays = (scap.EndDate.Value - scap.StartDate.Value).Days + 1;
decimal weeks = Math.Round(scapDurationInDays * 0.1427m, 2, MidpointRounding.AwayFromZero);
decimal total = weeks*scap.ApprovedBEPerInterval.Value;
decimal ah = 0;
if (scapDurationInDays != 0)
ah = total/scapDurationInDays;
return ah;
}
return base.GetApprovedHoursPerDay(scap, costRatePeriods);
}
public override decimal? GetApprovedHoursForPeriod(SupportConceptApprovalPeriodDC scap,
List<CostRatePeriodDC> costRatePeriods,
DateTime? pStart,
DateTime? pEnd)
{
//if (!pStart.HasValue || !pEnd.HasValue || scap.ApprovedFixedAmount.HasValue)
if (!pStart.HasValue || !pEnd.HasValue)
{
return null;
}
if (!scap.ApprovedBEPerInterval.HasValue)
return base.GetApprovedHoursForPeriod(scap, costRatePeriods, pStart, pEnd);
var hourlyRatesInSpanList = costRatePeriods.GetSpans(CostRatePeriodType.HourlyRate,
pStart.Value.Date, pEnd.Value.Date).ToList();
if (hourlyRatesInSpanList.Count > 1)
{
DateTime start = pStart.Value;
DateTime end = pEnd.Value;
decimal totalHours = 0;
for (int i = 0; i < hourlyRatesInSpanList.Count; i++)
{
if (start <= pEnd.Value)
{
var crp = hourlyRatesInSpanList.ElementAt(i).Key;
if (crp.EndDate.HasValue && crp.EndDate.Value < end)
end = crp.EndDate.Value.Date;
int periodInDays = (end - start).Days + 1;
decimal weeks = Math.Round(periodInDays * 0.1427m, 2, MidpointRounding.AwayFromZero);
decimal total = Math.Round(weeks * scap.ApprovedBEPerInterval.Value, 2, MidpointRounding.AwayFromZero);
totalHours += total;
start = end.AddDays(1);
end = pEnd.Value;
}
}
return totalHours;
}
else
{
var periodInDays = (pEnd.Value.Date - pStart.Value.Date).Days + 1;
return this.GetApprovedHoursPerDay(scap, costRatePeriods) * periodInDays;
}
}
public override decimal? GetApprovedAmountDefaultHourlyRateForPeriod(SupportConceptApprovalPeriodDC scap,
List<CostRatePeriodDC> costRatePeriods,
DateTime? start,
DateTime? end)
{
if (!start.HasValue || !end.HasValue)
return null;
var approvedHoursPerDay = this.GetApprovedHoursPerDay(scap, costRatePeriods);
if (!approvedHoursPerDay.HasValue)
{
return null;
}
decimal? result = 0m;
var day = start.Value.Date;
do
{
var hourlyRate = costRatePeriods.GetCostRatePeriodForDate(CostRatePeriodType.HourlyRate, day);
if (hourlyRate != null)
{
var amountThisDay = approvedHoursPerDay * hourlyRate.CostRateValue;
result += amountThisDay;
}
}
while ((day = day.AddDays(1)) <= end.Value.Date);
return result;
}
public override decimal? GetBillableAmount(ServiceRecordDC record)
{
decimal rdMinutes = record.RoundedDuration;
if (record.ServiceDescription.Category.Percentage != 100)
{
rdMinutes = (rdMinutes * record.ServiceDescription.Category.Percentage) / 100;
}
var hourlyRate = this.GetHourlyRatePeriodForServiceRecord(record);
if (hourlyRate != null && hourlyRate.CostRateValue.HasValue)
{
return (rdMinutes / 60m) * hourlyRate.CostRateValue.Value;
}
return null;
}
public override decimal GetDurationInMinutesForBillableAmount(ServiceRecordDC record, decimal amount)
{
var hourlyRate = this.GetHourlyRatePeriodForServiceRecord(record);
if (hourlyRate != null && hourlyRate.CostRateValue.HasValue)
return (amount / hourlyRate.CostRateValue.Value) * 60m;
return 0;
}
public override decimal? GetApprovedAmount(AccountingPeriod ap, SupportConceptApprovalPeriodDC scap)
{
decimal t1;
decimal t2;
if (scap.ApprovedFixedAmount.HasValue)
return this.GetApprovedFixedAmountForPeriod(scap, ap.PeriodStart, ap.PeriodEnd, out t1, out t2);
var approvedBETotal = this.GetApprovedBETotalInPeriod(scap, ap.CostRatesInPeriod, ap.PeriodStart, ap.PeriodEnd);
if (!approvedBETotal.HasValue)
{
return null;
}
decimal? result = null;
var hourlyRate = ap.CostRatesInPeriod.GetCostRatePeriodForDate(CostRatePeriodType.HourlyRate, ap.PeriodStart);
if (hourlyRate != null && hourlyRate.CostRateValue.HasValue)
{
result = Math.Round(approvedBETotal.Value, 2, MidpointRounding.AwayFromZero) * hourlyRate.CostRateValue;
}
return result;
}
public override decimal? GetApprovedBETotalInPeriod(SupportConceptApprovalPeriodDC scap,
List<CostRatePeriodDC> costRatePeriods,
DateTime start, DateTime end)
{
return costRatePeriods.GetCurrentlyValidRate(CostRatePeriodType.MinutesPerServiceUnit)
.GetHoursInBE(this.GetApprovedHoursForPeriodLWL(scap, costRatePeriods, start, end));
}
private decimal? GetApprovedHoursForPeriodLWL(SupportConceptApprovalPeriodDC scap,
List<CostRatePeriodDC> costRatePeriods,
DateTime start, DateTime end)
{
int periodInDays = (end - start).Days + 1;
decimal? approvedBEPerWeek = null;
if (scap.ApprovedBEPerInterval.HasValue && scap.ApprovedBEInterval.HasValue && scap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Weekly)
approvedBEPerWeek = scap.ApprovedBEPerInterval.Value;
else
approvedBEPerWeek = base.GetApprovedHoursPerWeek(scap, costRatePeriods);
if (approvedBEPerWeek.HasValue)
{
approvedBEPerWeek = Math.Round(approvedBEPerWeek.Value, 2, MidpointRounding.AwayFromZero);
decimal weeks = Math.Round(periodInDays * 0.1427m, 2, MidpointRounding.AwayFromZero);
decimal total = weeks * approvedBEPerWeek.Value;
return total;
}
return this.GetApprovedHoursPerDay(scap, costRatePeriods) * periodInDays;
}
public override int GetRoundedDuration(int minuteInterval, decimal durationInMinutes)
{
decimal lRoundedDuration = durationInMinutes;
if (minuteInterval > 0 && durationInMinutes >= 5)
{
lRoundedDuration = durationInMinutes % minuteInterval != 0
? durationInMinutes + (minuteInterval - (durationInMinutes % minuteInterval))
: durationInMinutes;
}
return (int)Math.Round(lRoundedDuration, 0, MidpointRounding.AwayFromZero);
}
}
}