234 lines
9.7 KiB
C#
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);
|
|
}
|
|
}
|
|
} |