Files
BeWoPlaner/Service/Invoicing/SettlementInvoiceCreation.cs
2020-08-17 15:50:00 +02:00

1347 lines
47 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeWo.Service.Plugins;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
namespace BeWo.Service.Invoicing
{
public class SettlementInvoiceCreation : AbstractIDSpecificDefaultClass<SettlementInvoiceCreation>
{
public virtual Settlement2DC GenerateSettlementInvoice(CostBearer2SupportConcept c2s, DateTime? periodStart, DateTime? periodEnd)
{
Settlement2DC settlementInvoice = new Settlement2DC();
settlementInvoice.CostBearer2SupportConceptOid = c2s.Oid;
settlementInvoice.CustomerReferenceNumber = c2s.CustomerReferenceNumber;
settlementInvoice.InvoiceDate = DateTime.Now.Date;
settlementInvoice.ServiceUnit = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(c2s.CostBearer.CostRatePeriods)
.GetCostRatePeriodForDate(CostRatePeriodType.MinutesPerServiceUnit, DateTime.Now);
if (settlementInvoice.ServiceUnit == null)
{
settlementInvoice.ServiceUnit = new CostRatePeriodDC();
settlementInvoice.ServiceUnit.CostRateType = CostRatePeriodType.MinutesPerServiceUnit;
settlementInvoice.ServiceUnit.UnitName = "FLS";
settlementInvoice.ServiceUnit.CostRateValue = 60;
}
if (String.IsNullOrEmpty(settlementInvoice.InvoiceNumber))
{
var inc = PluginLoader.FindClass<InvoiceNumberGenerator>();
settlementInvoice.InvoiceNumber = inc.GetNextInvoiceNumber(0, settlementInvoice);
}
if (periodStart.HasValue && periodEnd.HasValue)
{
settlementInvoice.AccountingPeriodStart = periodStart;
settlementInvoice.AccountingPeriodEnd = periodEnd;
}
else
{
settlementInvoice.AccountingPeriodStart = c2s.StartDate;
settlementInvoice.AccountingPeriodEnd = c2s.EndDate;
}
CreateSenderInformation(settlementInvoice);
CreateRecipientInformation(settlementInvoice, c2s);
if (CanCreateInvoiceTheOldWay(settlementInvoice, c2s))
CreateInvoiceDetailsTheOldWay(settlementInvoice, c2s);
else
CreateInvoiceDetails(settlementInvoice, c2s, periodStart, periodEnd);
if (settlementInvoice.InvoiceItems == null || settlementInvoice.InvoiceItems.Count == 0)
{
settlementInvoice.InvoiceItems = new List<InvoiceItemDC>();
settlementInvoice.InvoiceItems.Add(
new InvoiceItemDC
{
AmountTotal = settlementInvoice.Claim,
ItemPeriodStart = settlementInvoice.AccountingPeriodStart,
ItemPeriodEnd = settlementInvoice.AccountingPeriodEnd,
ItemDescription = "Spitzabrechnung"
});
}
return settlementInvoice;
}
public virtual IList<ServiceRecord> GetBillableServiceRecords(CostBearer2SupportConcept c2s)
{
return c2s.ServiceRecords;
}
public virtual bool CanCreateInvoiceTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s)
{
//Die alte Methode funktioniert nicht mehr wenn
//1. Es mehr als drei Stundensätze gibt
//2. Es mehr als einen Faktor gibt
//3. Mindestens einem Bewilligungszeitraum eine Kategorie zugeordnet ist
//4. Wenn sich Bewilligungszeiträume überscheiden
//5. ServiceRecords einer ServiceDescription/Category mit Stundensätzen zugeordnet sind
//In allen anderen Fällen wird die alte Methode noch verwendet, das sonst alle Kundenrechnungsformulare angepasst werden müssten.
//Prüfe 1:
var relDC = c2s.MapToNewDC();
DateTime start = si.AccountingPeriodStart.Value.Date;
DateTime end = si.AccountingPeriodEnd.Value.Date;
if (c2s.SupportConcept.Customer.TerminationDate.HasValue &&
c2s.SupportConcept.Customer.TerminationDate.Value < end)
{
end = c2s.SupportConcept.Customer.TerminationDate.Value;
}
if (end > DateTime.Now)
{
var srList = c2s.ServiceRecords;
var max = srList.Max(s => s.End);
if (max.HasValue && max < end)
{
end = max.Value;
}
}
var hourlyRatesInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.HourlyRate, start, end).ToList();
if (hourlyRatesInSpanList.Count > 3)
return false;
var factorInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor, start, end).ToList();
if (factorInSpanList.Count > 1)
return false;
//Prüfe 3
//for (int i = 0; i < c2s.ApprovalPeriodList.Count - 1; i++)
//{
// var ap1 = c2s.ApprovalPeriodList[i];
// if (ap1.StartDate.HasValue && ap1.EndDate.HasValue)
// {
// for (int j = i + 1; j < c2s.ApprovalPeriodList.Count; j++)
// {
// var ap2 = c2s.ApprovalPeriodList[j];
// if (ap2.StartDate.HasValue && ap2.EndDate.HasValue)
// {
// if (ap1.EndDate >= ap2.StartDate && ap1.StartDate <= ap2.EndDate)
// return false;
// }
// }
// }
//}
//Prüfe 2
foreach (var ap in c2s.ApprovalPeriodList)
{
if (ap.ServiceCategory != null && ap.ServiceCategory.IsActive == ActivationTypeId.Active)
{
if (ap.ServiceCategory.CostRatePeriods != null && ap.ServiceCategory.CostRatePeriods.Count > 0)
{
foreach (var costRatePeriod in ap.ServiceCategory.CostRatePeriods)
{
if (costRatePeriod.CostRateValue.HasValue && costRatePeriod.CostRateValue.Value > 0)
return false;
}
}
var sdList = DAOFactory.SearchDAO.FindServiceDescriptionForCategory(ap.ServiceCategory.Oid.Value);
foreach (var sd in sdList)
{
if (sd.CostRatePeriods.Count > 0)
{
foreach (var costRatePeriod in sd.CostRatePeriods)
{
if (costRatePeriod.CostRateValue.HasValue && costRatePeriod.CostRateValue.Value > 0)
return false;
}
}
}
}
}
//Prüfe 4
foreach (var sr in GetBillableServiceRecords(c2s))
{
if (IsServiceRecordBillable(sr) && sr.DurationMinutes > 0)
{
if (sr.ServiceDescription.CostRatePeriods.Count > 0)
{
foreach (var costRatePeriod in sr.ServiceDescription.CostRatePeriods)
{
if (costRatePeriod.CostRateValue.HasValue && costRatePeriod.CostRateValue.Value > 0)
return false;
}
}
if (sr.ServiceDescription.ServiceCategory.CostRatePeriods.Count > 0)
{
foreach (var costRatePeriod in sr.ServiceDescription.ServiceCategory.CostRatePeriods)
{
if (costRatePeriod.CostRateValue.HasValue && costRatePeriod.CostRateValue.Value > 0)
return false;
}
}
}
}
return true;
}
public virtual 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))
{
decimal rd = iRecord.RoundedDuration;
if (iRecord.ServiceDescription.ServiceCategory.Percentage != 100)
{
rd = (rd*iRecord.ServiceDescription.ServiceCategory.Percentage)/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;
}
public virtual bool CheckMaxApprovedHours()
{
return true;
}
public virtual bool IsServiceRecordBillable(ServiceRecord iRecord)
{
return true;
}
public virtual decimal? CalculateMaxAmount(Settlement2DC si)
{
return null;
}
public virtual void CreateInvoiceDetails(Settlement2DC si, CostBearer2SupportConcept c2s, DateTime? periodStart,
DateTime? periodEnd)
{
var calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
var records = GetBillableServiceRecords(c2s);
DateTimeSpan span = null;
if (periodStart.HasValue && periodEnd.HasValue)
{
span = new DateTimeSpan();
span.StartDateTime = periodStart.Value;
span.EndDateTime = periodEnd.Value;
records =
records.Where(
i => i.Start.HasValue && i.Start.Value.InBetween(periodStart.Value, periodEnd.Value, true))
.ToList();
}
foreach (var sr in records)
{
if (sr.GroupOid.HasValue)
{
si.HasGroupRecords = true;
}
}
var recordDCS = records.MapToNewDCsCompact();
var relDC = c2s.MapToNewDC();
CalculateSettlementInvoiceApprovedAmounts(si, relDC, calc);
var accountingPeriods = calc.GetAccountingPeriods(relDC, recordDCS, span);
foreach (var ap in accountingPeriods)
{
if (ap.SupportConceptApprovalPeriod != null && !ap.SupportConceptApprovalPeriod.ApprovedBETotal.HasValue)
{
ap.SupportConceptApprovalPeriod.ApprovedBETotal = si.ApprovedFLS;
}
}
si.InvoiceItems = CreateInvoiceItemsForAccountingPeriods(si, accountingPeriods, relDC.CostBearer.CostRatePeriods, calc);
if (si.ApprovedFLS.HasValue)
{
CalculateInvoiceItemAmounts(si);
}
//CalculateMaxApprovedAmounts(accountingPeriods, relDC.CostBearer.CostRatePeriods, calc);
CalculateAdvancedPayments(si, c2s);
CalculateEquityContribution(si, c2s.SupportConcept, periodStart, periodEnd);
CalculateSettlementInvoiceAmounts(si);
}
//public virtual void CalculateMaxApprovedAmounts(IList<AccountingPeriod> accountingPeriods, List<CostRatePeriodDC> costRatePeriods, Calculations calc)
//{
// Dictionary<long, SupportConceptApprovalPeriodDC> oid2Scap = new Dictionary<long, SupportConceptApprovalPeriodDC>();
// foreach (var ap in accountingPeriods)
// {
// var scap = ap.SupportConceptApprovalPeriod;
// SupportConceptApprovalPeriodDC scapHelper = null;
// if (scap != null)
// {
// if (oid2Scap.ContainsKey(scap.SupportConceptApprovalPeriodOid.Value))
// scapHelper = oid2Scap[scap.SupportConceptApprovalPeriodOid.Value];
// else
// {
// scapHelper = new SupportConceptApprovalPeriodDC();
// scapHelper.ApprovedBETotal = scap.ApprovedBETotal;
// if (!scapHelper.ApprovedBETotal.HasValue)
// scapHelper.ApprovedBETotal = calc.GetApprovedBETotal(scap, costRatePeriods);
// }
// }
// if (scapHelper.ApprovedBETotal.HasValue && scapHelper.ApprovedBETotal > ap.co
// }
//}
public virtual void CalculateSettlementInvoiceAmounts(Settlement2DC si)
{
decimal maxAmount = 0;
if (si.InvoiceItems != null)
{
si.AmountBillableTotal = si.InvoiceItems.Sum(ii => Math.Round(ii.GrossAmountTotal ?? 0, 2, MidpointRounding.AwayFromZero));
//maxAmount = si.InvoiceItems.Sum(ii =>
// {
// decimal amount = ii.GrossAmountTotal ?? 0;
// if (ii.MaxApprovedAmount.HasValue && ii.MaxApprovedAmount.Value > 0 && ii.MaxApprovedAmount < amount)
// amount = ii.MaxApprovedAmount.Value;
// return amount;
// });
if (maxAmount == 0)
maxAmount = si.AmountBillableTotal.Value;
}
si.Claim = maxAmount - (si.AmountAdvancedPayments ?? 0) - (si.EquityContribution ?? 0);
}
public virtual List<InvoiceItemDC> CreateInvoiceItemsForAccountingPeriods(Settlement2DC si, List<AccountingPeriod> accountingPeriods,
List<CostRatePeriodDC> costRatePeriods, Calculations calc)
{
Dictionary<long, SupportConceptApprovalPeriodDC> oid2Scap = new Dictionary<long, SupportConceptApprovalPeriodDC>();
List<InvoiceItemDC> invoiceItems = new List<InvoiceItemDC>();
foreach (var ap in accountingPeriods)
{
InvoiceItemDC ii = CreateInvoiceItemForAccountingPeriod(ap);
invoiceItems.Add(ii);
var scap = ap.SupportConceptApprovalPeriod;
SupportConceptApprovalPeriodDC scapHelper = null;
if (scap != null)
{
if (oid2Scap.ContainsKey(scap.SupportConceptApprovalPeriodOid.Value))
scapHelper = oid2Scap[scap.SupportConceptApprovalPeriodOid.Value];
else
{
scapHelper = new SupportConceptApprovalPeriodDC();
scapHelper.ApprovedBETotal = scap.ApprovedBETotal;
if (!scapHelper.ApprovedBETotal.HasValue)
scapHelper.ApprovedBETotal = calc.GetApprovedBETotal(scap, costRatePeriods);
oid2Scap[scap.SupportConceptApprovalPeriodOid.Value] = scapHelper;
}
}
if (!si.ApprovedFLS.HasValue)
{
if (scapHelper.ApprovedBETotal.HasValue && ii.UnitCount.HasValue)
{
if (scapHelper.ApprovedBETotal >= ii.UnitCount.Value)
{
scapHelper.ApprovedBETotal -= ii.UnitCount.Value;
ii.MaxApprovedUnitCount = null;
}
else
{
ii.MaxApprovedUnitCount = scapHelper.ApprovedBETotal;
}
}
CalculateInvoiceItemAmounts(ii);
}
if (ii.UnitCount.HasValue)
{
si.RecordedBillableFLSBrutto = (si.RecordedBillableFLSBrutto ?? 0) + ii.UnitCount;
}
var list = CreateAdditionalInvoiceItems(ap);
invoiceItems.AddRange(list);
}
return invoiceItems;
}
public virtual IList<InvoiceItemDC> CreateAdditionalInvoiceItems(AccountingPeriod ap)
{
//only for subclasses
return new List<InvoiceItemDC>();
}
public virtual InvoiceItemDC CreateInvoiceItemForAccountingPeriod(AccountingPeriod accountingPeriod)
{
InvoiceItemDC ii = new InvoiceItemDC();
ii.AccountingInterval = accountingPeriod.AccountingInterval;
ii.ItemPeriodStart = accountingPeriod.PeriodStart;
ii.ItemPeriodEnd = accountingPeriod.PeriodEnd;
ii.RateFactor = accountingPeriod.RateFactor;
ii.AmountPerUnit = accountingPeriod.Amount;
ii.UnitDescription = accountingPeriod.UnitName;
ii.MaxApprovedAmount = accountingPeriod.MaxApprovedAmount;
ii.MaxApprovedUnitCount = accountingPeriod.MaxApprovedUnitCount;
ii.ApprovedPerUnit = accountingPeriod.ApprovedPerUnit;
ii.ApprovalUnit = accountingPeriod.ApprovalUnit;
if (accountingPeriod.ServiceCategory != null)
ii.ItemDescription = accountingPeriod.ServiceCategory.Name;
if (accountingPeriod.AccountingInterval == AccountingIntervalType.FlatRate)
{
ii.UnitCount = accountingPeriod.ServiceRecordsInPeriod.Count;
}
else if (accountingPeriod.AccountingInterval == AccountingIntervalType.Hourly)
{
decimal minutesTotal = 0;
if (accountingPeriod.ServiceRecordsInPeriod != null)
{
foreach (var ar in accountingPeriod.ServiceRecordsInPeriod)
{
var rd = ar.RoundedDuration;
if (ar.ServiceDescription.Category.Percentage != 100)
{
rd = (rd*ar.ServiceDescription.Category.Percentage)/100;
}
minutesTotal += rd;
}
}
ii.UnitCount = minutesTotal/60;
if (String.IsNullOrEmpty(ii.UnitDescription))
ii.UnitDescription = ii.UnitCount.Value == 1 ? "Stunde" : "Stunden";
}
else if (accountingPeriod.PeriodStart > DateTime.MinValue && accountingPeriod.PeriodEnd < DateTime.MaxValue)
{
DateTime intervalStart = accountingPeriod.PeriodStart;
DateTime intervalEnd = intervalStart;
int count = 0;
while (intervalStart < accountingPeriod.PeriodEnd)
{
count++;
switch (accountingPeriod.AccountingInterval)
{
case AccountingIntervalType.Daily:
intervalEnd = intervalStart.AddDays(1);
break;
case AccountingIntervalType.Weekly:
intervalEnd = intervalStart.AddDays(7);
break;
case AccountingIntervalType.Fortnightly:
intervalEnd = intervalStart.AddDays(14);
break;
case AccountingIntervalType.Monthly:
intervalEnd = intervalStart.AddMonths(1);
break;
case AccountingIntervalType.Quarterly:
intervalEnd = intervalStart.AddMonths(3);
break;
case AccountingIntervalType.HalfYearly:
intervalEnd = intervalStart.AddMonths(6);
break;
case AccountingIntervalType.Yearly:
intervalEnd = intervalStart.AddYears(1);
break;
}
intervalStart = intervalEnd;
}
ii.UnitCount = count;
switch (accountingPeriod.AccountingInterval)
{
case AccountingIntervalType.Daily:
ii.UnitDescription = count == 1 ? "Tag" : "Tage";
break;
case AccountingIntervalType.Weekly:
ii.UnitDescription = count == 1 ? "Woche" : "Wochen";
break;
case AccountingIntervalType.Fortnightly:
ii.UnitDescription = "2 Wochen";
break;
case AccountingIntervalType.Monthly:
ii.UnitDescription = count == 1 ? "Monat" : "Monate";
break;
case AccountingIntervalType.Quarterly:
ii.UnitDescription = count == 1 ? "Quartal" : "Quartale";
break;
case AccountingIntervalType.HalfYearly:
ii.UnitDescription = "Halbjährlich";
break;
case AccountingIntervalType.Yearly:
ii.UnitDescription = count == 1 ? "Jahr" : "Jahre";
break;
}
}
return ii;
}
public virtual void CalculateInvoiceItemAmounts(InvoiceItemDC ii)
{
if (ii.UnitCount.HasValue)
{
var uc = ii.UnitCount.Value;
if (ii.MaxApprovedUnitCount.HasValue && ii.MaxApprovedUnitCount.Value < uc)
uc = ii.MaxApprovedUnitCount.Value;
ii.UnitCount = Math.Round(uc, 2, MidpointRounding.AwayFromZero);
if (ii.AmountPerUnit.HasValue)
{
ii.AmountTotal = Math.Round(ii.UnitCount.Value*ii.AmountPerUnit.Value, 2,
MidpointRounding.AwayFromZero);
if (ii.RateFactor.HasValue && ii.RateFactor.Value != 0)
ii.GrossAmountTotal = Math.Round(ii.AmountTotal.Value*((100m + ii.RateFactor.Value)/100m), 2,
MidpointRounding.AwayFromZero);
else
ii.GrossAmountTotal = ii.AmountTotal;
}
}
}
public virtual void CalculateInvoiceItemAmounts(Settlement2DC si)
{
decimal maxApprovedFls = si.ApprovedFLS ?? 0;
foreach (var ii in si.InvoiceItems)
{
if (ii.UnitCount.HasValue)
{
var uc = Math.Round(ii.UnitCount ?? 0, 2, MidpointRounding.AwayFromZero);
if (maxApprovedFls < uc)
uc = maxApprovedFls;
maxApprovedFls -= uc;
ii.UnitCount = uc;
if (ii.AmountPerUnit.HasValue)
{
ii.AmountTotal = ii.UnitCount.Value * ii.AmountPerUnit.Value;
if (ii.RateFactor.HasValue && ii.RateFactor.Value != 0)
ii.GrossAmountTotal = Math.Round(ii.AmountTotal.Value * ((100m + ii.RateFactor.Value) / 100m), 2,
MidpointRounding.AwayFromZero);
else
ii.GrossAmountTotal = ii.AmountTotal;
}
if (ii.MaxApprovedUnitCount < ii.UnitCount)
{
ii.MaxApprovedUnitCount = ii.UnitCount;
}
}
}
}
public virtual void CalculateSettlementInvoiceApprovedAmounts(Settlement2DC si, SupportConceptCostBearerRelDC relDC,
Calculations calc)
{
decimal flsWeek = calc.GetApprovedHoursPerWeekAverage(relDC, true) ?? 0m;
decimal flsTotal = calc.GetApprovedHoursTotal(relDC, true) ?? 0m;
flsTotal = Math.Round(flsTotal, 2, MidpointRounding.AwayFromZero);
si.ApprovedFLS = flsTotal;
si.ApprovedFLSWeekly = flsWeek;
}
public virtual void CreateRecipientInformation(Settlement2DC settlementInvoice, CostBearer2SupportConcept c2s)
{
if (c2s.CostBearer != null && c2s.CostBearer.Organisation != null)
{
settlementInvoice.RecipientOrganisation = c2s.CostBearer.Organisation.Name;
settlementInvoice.RecipientDivision = c2s.CostBearer.Organisation.Name2;
}
if (c2s.CostBearerContactPerson != null)
{
settlementInvoice.RecipientContactPerson = c2s.CostBearerContactPerson.ToString();
}
else if (c2s.CostBearer != null && c2s.CostBearer.Organisation != null)
{
var lContactPerson = c2s.CostBearer.Organisation.Contacts.SingleOrDefault(c => c.Type == ContactType.ContactPerson);
if (lContactPerson != null)
{
settlementInvoice.RecipientContactPerson = lContactPerson.Value;
}
}
// War die private Rechnungsadresse der Kontaktperson
//if (c2s.CostBearerContactPerson != null && c2s.CostBearerContactPerson.InvoiceAddress != null)
//{
// settlementInvoice.RecipientPostCode = c2s.CostBearerContactPerson.InvoiceAddress.PostalCode;
// settlementInvoice.RecipientStreet = c2s.CostBearerContactPerson.InvoiceAddress.Street;
// settlementInvoice.RecipientTown = c2s.CostBearerContactPerson.InvoiceAddress.Town;
//}
//else
if (c2s.CostBearer != null && c2s.CostBearer.Organisation != null)
{
if (c2s.CostBearer.Organisation.InvoiceAddress != null &&
!String.IsNullOrEmpty(c2s.CostBearer.Organisation.InvoiceAddress.Street))
{
settlementInvoice.RecipientPostCode = c2s.CostBearer.Organisation.InvoiceAddress.PostalCode;
settlementInvoice.RecipientStreet = c2s.CostBearer.Organisation.InvoiceAddress.Street;
settlementInvoice.RecipientTown = c2s.CostBearer.Organisation.InvoiceAddress.Town;
}
else if (c2s.CostBearer.Organisation.Address != null)
{
settlementInvoice.RecipientPostCode = c2s.CostBearer.Organisation.Address.PostalCode;
settlementInvoice.RecipientStreet = c2s.CostBearer.Organisation.Address.Street;
settlementInvoice.RecipientTown = c2s.CostBearer.Organisation.Address.Town;
}
settlementInvoice.RecipientPostBox = c2s.CostBearer.Organisation.Contacts.FirstOrDefault(f => f.Type.Equals(ContactType.business_POBox)) != null ? c2s.CostBearer.Organisation.Contacts.FirstOrDefault(f => f.Type.Equals(ContactType.business_POBox)).Value : String.Empty;
}
}
public virtual void CreateSenderInformation(Settlement2DC settlementInvoice)
{
if (LoggedInUserOperationContextExt.Current != null)
{
var lLoggedInEmployee = LoggedInUserOperationContextExt.Current.User.Employee;
if (lLoggedInEmployee != null)
{
settlementInvoice.SenderContactPersonFirstName = lLoggedInEmployee.Person.FirstName;
settlementInvoice.SenderContactPersonLastName = lLoggedInEmployee.Person.LastName;
foreach (var iContact in lLoggedInEmployee.Person.Contacts)
{
switch (iContact.Type)
{
case ContactType.business_Fax:
settlementInvoice.SenderContactPersonFax = iContact.Value;
break;
case ContactType.business_Mail:
settlementInvoice.SenderContactPersonMail = iContact.Value;
break;
case ContactType.business_Phone:
settlementInvoice.SenderContactPersonPhone = iContact.Value;
break;
}
}
settlementInvoice.CreatorFirstName = lLoggedInEmployee.Person.FirstName;
settlementInvoice.CreatorLastName = lLoggedInEmployee.Person.LastName;
}
}
}
public virtual void CalculateAdvancedPayments(Settlement2DC settlementInvoice, CostBearer2SupportConcept cb2sc)
{
if (settlementInvoice.InvoiceItems != null && settlementInvoice.InvoiceItems.Count > 0)
{
decimal amountTotal = 0;
var bookingList = cb2sc.AccountingTransactions;
foreach (var item in bookingList)
{
if (item.GueltigkeitsDatum.HasValue)
{
foreach (var ii in settlementInvoice.InvoiceItems)
{
if (ii.ItemPeriodStart.HasValue && ii.ItemPeriodEnd.HasValue)
{
if (item.GueltigkeitsDatum.Value.InBetween(ii.ItemPeriodStart.Value, ii.ItemPeriodEnd.Value, true))
{
ii.ReceivedAmount += item.Amount;
break;
}
}
}
}
amountTotal += item.Amount;
}
settlementInvoice.AmountAdvancedPayments = amountTotal;
}
}
public virtual void CalculateAdvancedPayments(Settlement2DC settlementInvoice, CostBearer2SupportConcept cb2sc,
DateTime? periodStart, DateTime? periodEnd, List<KeyValuePair<CostRatePeriodDC, DateTimeSpan>> hourlyRatesInSpanList)
{
decimal amountNew = 0;
decimal amountOld = 0;
decimal amount3 = 0;
decimal amountTotal = 0;
var bookingList = cb2sc.AccountingTransactions;
if (periodStart.HasValue && periodEnd.HasValue)
{
bookingList =
bookingList.Where(i => i.GueltigkeitsDatum.HasValue
&& i.GueltigkeitsDatum.Value.InBetween(periodStart.Value, periodEnd.Value, true)).ToList();
}
foreach (var item in bookingList)
{
if (hourlyRatesInSpanList.Count > 2 && item.GueltigkeitsDatum != null &&
item.GueltigkeitsDatum < hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 2].Value.StartDateTime)
{
amount3 += item.Amount;
}
else if (hourlyRatesInSpanList.Count > 1 && item.GueltigkeitsDatum != null &&
item.GueltigkeitsDatum < hourlyRatesInSpanList[hourlyRatesInSpanList.Count - 1].Value.StartDateTime)
{
amountOld += item.Amount;
}
else
{
amountNew += item.Amount;
}
amountTotal += item.Amount;
}
settlementInvoice.AmountTotalAdvancedPaidWithNewHourlyRate = amountNew;
settlementInvoice.AmountTotalAdvancedPaidWithOldHourlyRate = amountOld;
settlementInvoice.AmountTotalAdvancedPaidWithHourlyRate3 = amount3;
settlementInvoice.AmountAdvancedPayments = amountTotal;
}
public virtual void CalculateEquityContribution(Settlement2DC settlementInvoice, SupportConcept sc,
DateTime? periodStart, DateTime? periodEnd)
{
decimal equity = 0;
IList<InvoiceBase> invoiceList =
DAOFactory.SearchDAO.GetInvoiceBaseByTypeAndSupportConceptOid(InvoiceType.CustomerEquity, sc.Oid.Value);
if (periodStart.HasValue && periodEnd.HasValue)
{
invoiceList =
invoiceList.Where(i => i.InvoiceDate.HasValue
&& i.InvoiceDate.Value.InBetween(periodStart.Value, periodEnd.Value, true)).ToList();
}
foreach (InvoiceBase invoice in invoiceList)
{
foreach (InvoiceItem item in invoice.InvoiceItems)
{
if (item.AmountTotal != null)
{
equity += item.AmountTotal.Value;
}
}
}
settlementInvoice.EquityContribution = equity;
}
public virtual IList<ApprovalPeriod> CreateApprovalPeriods(Settlement2DC si, CostBearer2SupportConcept c2s)
{
var relDc = c2s.MapToNewDC();
var hourlyRatesInSpanList = relDc.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.HourlyRate,
si.AccountingPeriodStart.Value.Date, si.AccountingPeriodEnd.Value.Date).ToList();
List<ApprovalPeriod> sonstigeAp = new List<ApprovalPeriod>();
Dictionary<DateTime, ApprovalPeriod> dtApDict = new Dictionary<DateTime, ApprovalPeriod>();
foreach (var keyValuePair in hourlyRatesInSpanList)
{
var ap = new ApprovalPeriod();
ap.PeriodStartDate = keyValuePair.Value.StartDate;
ap.PeriodEndDate = DateTime.MaxValue;
dtApDict.Add(ap.PeriodStartDate, ap);
}
var rateFactorInSpanList = relDc.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor,
si.AccountingPeriodStart.Value.Date, si.AccountingPeriodEnd.Value.Date).ToList();
foreach (var keyValuePair in rateFactorInSpanList)
{
if (!dtApDict.ContainsKey(keyValuePair.Value.StartDate))
{
var ap = new ApprovalPeriod();
ap.PeriodStartDate = keyValuePair.Value.StartDate;
ap.PeriodEndDate = DateTime.MaxValue;
dtApDict.Add(ap.PeriodStartDate, ap);
}
}
foreach (var scap in c2s.ApprovalPeriodList)
{
if (scap.StartDate.HasValue && scap.EndDate.HasValue)
{
if (!dtApDict.ContainsKey(scap.StartDate.Value) && scap.ApprovedBEInterval.HasValue &&
scap.ApprovedBEPerInterval.HasValue)
{
var ap = new ApprovalPeriod();
ap.PeriodStartDate = scap.StartDate.Value;
ap.PeriodEndDate = DateTime.MaxValue;
dtApDict.Add(ap.PeriodStartDate, ap);
}
else if (scap.ApprovedBETotal.HasValue)
{
var ap = new ApprovalPeriod();
ap.PeriodStartDate = scap.StartDate.Value;
ap.PeriodEndDate = scap.EndDate.Value;
ap.ApprovedTotal = scap.ApprovedBETotal.Value;
ap.ApprovalUnit = AccountingIntervalType.FlatRate;
var hrspan = hourlyRatesInSpanList.FirstOrDefault(ispan => ispan.Value.StartDate <= ap.PeriodStartDate && ap.PeriodStartDate <= ispan.Value.EndDate);
var rfspan = rateFactorInSpanList.FirstOrDefault(ispan => ispan.Value.StartDate <= ap.PeriodStartDate && ap.PeriodStartDate <= ispan.Value.EndDate);
if (hrspan.Key != null && hrspan.Key.CostRateValue.HasValue)
{
ap.AmountPerUnit = hrspan.Key.CostRateValue.Value;
ap.BillingInterval = AccountingIntervalType.Hourly;
}
if (rfspan.Key != null && rfspan.Key.CostRateValue.HasValue)
{
ap.RateFactor = rfspan.Key.CostRateValue.Value;
}
sonstigeAp.Add(ap);
}
}
}
foreach (var dt in dtApDict.Keys)
{
ApprovalPeriod ap = dtApDict[dt];
var hrspan = hourlyRatesInSpanList.FirstOrDefault(ispan => ispan.Value.StartDate <= dt && dt <= ispan.Value.EndDate);
var rfspan = rateFactorInSpanList.FirstOrDefault(ispan => ispan.Value.StartDate <= dt && dt <= ispan.Value.EndDate);
var scap = c2s.ApprovalPeriodList.FirstOrDefault(iscap => iscap.StartDate <= dt && dt <= iscap.EndDate && !iscap.ApprovedBETotal.HasValue);
if (hrspan.Key != null && hrspan.Key.CostRateValue.HasValue)
{
ap.AmountPerUnit = hrspan.Key.CostRateValue.Value;
ap.BillingInterval = AccountingIntervalType.Hourly;
}
if (hrspan.Value != null && hrspan.Value.EndDate < ap.PeriodEndDate)
{
ap.PeriodEndDate = hrspan.Value.EndDate;
}
if (rfspan.Key != null && rfspan.Key.CostRateValue.HasValue)
{
ap.RateFactor = rfspan.Key.CostRateValue.Value;
}
if (rfspan.Value != null && rfspan.Value.EndDate < ap.PeriodEndDate)
{
ap.PeriodEndDate = rfspan.Value.EndDate;
}
if (scap != null)
{
if (scap.EndDate.HasValue && scap.EndDate < ap.PeriodEndDate)
ap.PeriodEndDate = scap.EndDate.Value;
CalculateApprovedAmountForApprovalPeriod(ap, scap);
}
}
var list = dtApDict.Values.OrderBy(ap => ap.PeriodStartDate).ToList();
foreach (var ap in sonstigeAp)
{
list.Add(ap);
}
foreach (var approvalPeriod in list)
{
InitApprovalPeriod(si, approvalPeriod);
}
return list;
}
public virtual void CalculateApprovedAmountForApprovalPeriod(ApprovalPeriod ap, SupportConceptApprovalPeriod scap)
{
if (scap.ApprovedBEPerInterval.HasValue && scap.ApprovedBEInterval.HasValue)
{
ap.ApprovedPerUnit = scap.ApprovedBEPerInterval.Value;
ap.ApprovalUnit = Calculations.ConvertApprovalToAccountingIntervalType(scap.ApprovedBEInterval.Value);
}
else if (scap.ApprovedBETotal.HasValue)
{
//Gesamtstunden auf ap Zeitraum umrechnen
if (ap.PeriodStartDate == scap.StartDate && ap.PeriodEndDate == scap.EndDate)
{
ap.ApprovedPerUnit = scap.ApprovedBETotal.Value;
}
else if (scap.EndDate.HasValue && scap.StartDate.HasValue)
{
decimal perioddays = (decimal)ap.PeriodEndDate.Subtract(ap.PeriodStartDate).TotalDays + 1;
decimal totaldays = (decimal)scap.EndDate.Value.Subtract(scap.StartDate.Value).TotalDays + 1;
var approvedPerDay = scap.ApprovedBETotal.Value / totaldays;
ap.ApprovedPerUnit = perioddays * approvedPerDay;
}
else
{
ap.ApprovedPerUnit = scap.ApprovedBETotal.Value;
}
ap.ApprovalUnit = AccountingIntervalType.FlatRate;
}
}
public virtual void InitApprovalPeriod(Settlement2DC si, ApprovalPeriod approvalPeriod)
{
approvalPeriod.Days = approvalPeriod.PeriodEndDate.Subtract(approvalPeriod.PeriodStartDate).Days + 1;
approvalPeriod.Weeks = approvalPeriod.Days / 7m;
if (approvalPeriod.ApprovalUnit == AccountingIntervalType.FlatRate)
{
if (approvalPeriod.ApprovedTotal == 0)
{
approvalPeriod.ApprovedTotal = approvalPeriod.ApprovedPerUnit;
}
}
else if (approvalPeriod.ApprovalUnit == AccountingIntervalType.Monthly)
{
var months = GetTotalMonths(approvalPeriod.PeriodStartDate, approvalPeriod.PeriodEndDate);
approvalPeriod.ApprovedTotal = months * approvalPeriod.ApprovedPerUnit;
}
else if (approvalPeriod.ApprovalUnit == AccountingIntervalType.Quarterly)
{
var months = GetTotalQuarters(approvalPeriod.PeriodStartDate, approvalPeriod.PeriodEndDate);
approvalPeriod.ApprovedTotal = months * approvalPeriod.ApprovedPerUnit;
}
else
{
approvalPeriod.ApprovedTotal = Math.Round(approvalPeriod.Weeks * approvalPeriod.ApprovedPerUnit, 2,
MidpointRounding.AwayFromZero);
}
approvalPeriod.ApprovedAmountTotal = Math.Round(approvalPeriod.ApprovedTotal * approvalPeriod.AmountPerUnit, 2,
MidpointRounding.AwayFromZero);
}
public virtual decimal GetTotalMonths(DateTime start, DateTime end)
{
var am = DateTimeUtils.GetTotalMonths(start, end);
return am.AnzahlMonateGesamt;
}
public virtual decimal GetTotalQuarters(DateTime start, DateTime end)
{
int restTageStart = 0;
int restTageEnd = 0;
DateTime startDt = start;
DateTime endDt = end;
if (startDt.Day > 1)
{
var endMonat = new DateTime(startDt.Year, startDt.Month, 1).AddMonths(1).AddDays(-1);
if (endDt < endMonat)
{
endMonat = endDt;
}
restTageStart = endMonat.Subtract(startDt).Days + 1;
startDt = endMonat.AddDays(1);
}
DateTime startTemp = startDt;
int fullQuarters = 0;
while (startDt <= endDt)
{
startDt = startDt.AddMonths(3);
if (startDt <= endDt.AddDays(1))
{
startTemp = startDt;
fullQuarters++;
}
}
if (startTemp < endDt.AddDays(1))
{
restTageEnd = endDt.Subtract(startTemp).Days + 1;
}
decimal quartersTotal = fullQuarters;
if (restTageStart > 0)
{
quartersTotal += restTageStart / 90m;
}
if (restTageEnd > 0)
{
quartersTotal += restTageEnd / 90m;
}
return quartersTotal;
}
}
}