MH: VSDHammReports CustomSettlementInvoiceCreation Claude Vorbereitung
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
using BeWo.Data.Access;
|
||||
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.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static BeWo.Report.ReportObjects.SettlementRO;
|
||||
using BS.Shared.Extensions;
|
||||
|
||||
namespace VSDHammReports
|
||||
{
|
||||
@@ -22,11 +26,7 @@ namespace VSDHammReports
|
||||
public override bool SchneideBeiErreichenDesBudgetsAb { get { return true; } }
|
||||
|
||||
|
||||
public override void CreateInvoiceDetailsTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s)
|
||||
{
|
||||
base.CreateInvoiceDetailsTheOldWay(si, c2s);
|
||||
}
|
||||
|
||||
|
||||
public override List<InvoiceItemDC> CreateInvoiceItems(Settlement2DC si, IList<ApprovalPeriod> apList, bool schneideBeiMaxAb)
|
||||
{
|
||||
//var items = base.CreateInvoiceItems(si, apList, true);
|
||||
@@ -127,7 +127,237 @@ namespace VSDHammReports
|
||||
|
||||
}
|
||||
|
||||
public override void CreateInvoiceDetailsTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s)
|
||||
{
|
||||
String id = c2s.CostBearer.ID;
|
||||
|
||||
var calc = PluginLoader.FindClass<Calculations>(id);
|
||||
if (calc == null)
|
||||
{
|
||||
calc = Calculations.GetInstance(id);
|
||||
}
|
||||
|
||||
var relDc = c2s.MapToNewDC();
|
||||
|
||||
var apListFehlkontakt = new List<ApprovalPeriod>();
|
||||
var apListFLS = CreateApprovalPeriods(si, c2s);
|
||||
foreach (var ap in apListFLS)
|
||||
{
|
||||
var fkAp = new ApprovalPeriod();
|
||||
fkAp.PeriodStartDate = ap.PeriodStartDate;
|
||||
fkAp.PeriodEndDate = ap.PeriodEndDate;
|
||||
fkAp.AmountPerUnit = ap.AmountPerUnit;
|
||||
fkAp.BillingInterval = ap.BillingInterval;
|
||||
fkAp.RateFactor = 0;
|
||||
fkAp.Notice = "Fehlkontakte";
|
||||
apListFehlkontakt.Add(fkAp);
|
||||
}
|
||||
si.ApprovedFLS = CalculateApprovedTotalFLS(apListFLS);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var hourlyRatesInSpanList = relDc.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.HourlyRate, periodStart, periodEnd).ToList();
|
||||
|
||||
si.DifferentHourlyRateCount = hourlyRatesInSpanList.Count;
|
||||
if (si.DifferentHourlyRateCount == 0)
|
||||
{
|
||||
si.DifferentHourlyRateCount = 1;
|
||||
}
|
||||
var rateFactorsInSpanList = relDc.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor, periodStart, periodEnd).ToList();
|
||||
if (rateFactorsInSpanList.Count > 0)
|
||||
{
|
||||
var cdc = rateFactorsInSpanList.Last().Key;
|
||||
if (cdc.CostRateValue.HasValue)
|
||||
si.RateFactor = cdc.CostRateValue.Value;
|
||||
}
|
||||
decimal rf = GetRateFactor(si);
|
||||
|
||||
var records = c2s.ServiceRecords;
|
||||
|
||||
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 flmCleared = 0;
|
||||
|
||||
records = records.OrderBy<ServiceRecord, DateTime>(sr => sr.Start.HasValue ? sr.Start.Value : DateTime.MinValue).ToList<ServiceRecord>();
|
||||
decimal maxApprovedMinutes = (si.ApprovedFLS ?? 0) * 60;
|
||||
decimal totalMinutesGeleistet = 0;
|
||||
foreach (var iRecord in records)
|
||||
{
|
||||
if (iRecord.ServiceDescription.ServiceCategory.IsBillable)
|
||||
{
|
||||
if (iRecord.GroupOid == null || !groupBookingDict.ContainsKey(iRecord.GroupOid.Value))
|
||||
{
|
||||
|
||||
decimal dauerAbrechenbar = iRecord.RoundedDuration;
|
||||
decimal dauerBudget = iRecord.RoundedDuration;
|
||||
|
||||
if (ReduziereBetragBeiAbwesenheiten())
|
||||
{
|
||||
//Die Liste recordDCS enthält nach Aufruf von GetHoursNotBillableDueToAbsenceTimes nur noch die Einträge, die auch während Abwesenheiten abgerechnet werden dürfen
|
||||
var dcRecord = recordDCS.Where(r => r.ServiceRecordOid == iRecord.Oid).FirstOrDefault();
|
||||
if (dcRecord == null)
|
||||
{
|
||||
dauerAbrechenbar = 0;
|
||||
dauerBudget = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dauerAbrechenbar = dcRecord.RoundedDuration;
|
||||
dauerBudget = dcRecord.RoundedDuration;
|
||||
}
|
||||
}
|
||||
|
||||
//var prozent = iRecord.ServiceDescription.ServiceCategory.ProzentAbrechnung;
|
||||
//if (iRecord.ServiceDescription.ProzentAbrechnung.HasValue)
|
||||
//{
|
||||
// prozent = iRecord.ServiceDescription.ProzentAbrechnung.Value;
|
||||
//}
|
||||
//dauerAbrechenbar *= prozent / 100;
|
||||
|
||||
var prozent = iRecord.ServiceDescription.ServiceCategory.ProzentBudget ?? 100;
|
||||
if (iRecord.ServiceDescription.ProzentBudget.HasValue)
|
||||
{
|
||||
prozent = iRecord.ServiceDescription.ProzentBudget.Value;
|
||||
}
|
||||
dauerBudget *= prozent / 100;
|
||||
|
||||
var apList = apListFLS;
|
||||
if (iRecord.ServiceDescription.Name.ToLower().Contains("fehlkontakt") || (iRecord.ServiceDescription.ProzentAbrechnung.HasValue && iRecord.ServiceDescription.ProzentAbrechnung.Value < 100))
|
||||
{
|
||||
apList = apListFehlkontakt;
|
||||
}
|
||||
|
||||
var ap = apList.FirstOrDefault(
|
||||
iap =>
|
||||
{
|
||||
return iap.PeriodStartDate <= iRecord.Start &&
|
||||
(iap.PeriodEndDate >= DateTime.MaxValue.AddDays(-1) || iRecord.Start < iap.PeriodEndDate.AddDays(1));
|
||||
});
|
||||
|
||||
if (ap != null)
|
||||
{
|
||||
//Christian wars:-)
|
||||
var dauerBudgetMitRf = dauerBudget * ((ap.RateFactor ?? 0) + 100) / 100;
|
||||
if (SchneideBeiErreichenDesBudgetsAb)
|
||||
{
|
||||
if (totalMinutesGeleistet + dauerBudgetMitRf > maxApprovedMinutes)
|
||||
{
|
||||
dauerBudget = maxApprovedMinutes - totalMinutesGeleistet;
|
||||
dauerBudget /= ((ap.RateFactor ?? 0) + 100) / 100;
|
||||
|
||||
if (dauerBudget < 0)
|
||||
{
|
||||
dauerBudget = 0;
|
||||
}
|
||||
if (dauerAbrechenbar > dauerBudget)
|
||||
{
|
||||
dauerAbrechenbar = dauerBudget;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
totalMinutesGeleistet += dauerBudgetMitRf;
|
||||
|
||||
ap.RecordedMinutes += dauerAbrechenbar;
|
||||
ap.BudgetMinutes += dauerBudget;
|
||||
}
|
||||
|
||||
if (iRecord.GroupOid != null && !groupBookingDict.ContainsKey(iRecord.GroupOid.Value))
|
||||
{
|
||||
si.HasGroupRecords = true;
|
||||
groupBookingDict.Add(iRecord.GroupOid.Value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
si.RecordedMinutesTotal = totalMinutesGeleistet;
|
||||
|
||||
//decimal? maxAmount = CalculateMaxAmount(si, apList);
|
||||
var gesamtListe = new List<ApprovalPeriod>();
|
||||
gesamtListe.AddRange(apListFLS.Where(a => a.RecordedMinutes > 0));
|
||||
gesamtListe.AddRange(apListFehlkontakt.Where(a => a.RecordedMinutes > 0));
|
||||
si.InvoiceItems = CreateInvoiceItems(si, gesamtListe);
|
||||
|
||||
decimal totalAmount = 0;
|
||||
decimal rateFactorAmount = 0;
|
||||
|
||||
foreach (var ii in si.InvoiceItems)
|
||||
{
|
||||
decimal grossAmount = ii.GrossAmountTotal ?? 0;
|
||||
totalAmount += grossAmount;
|
||||
|
||||
if (ii.RateFactor.HasValue && ii.RateFactor.Value > 0)
|
||||
{
|
||||
rateFactorAmount += (grossAmount - (grossAmount / ((100 + ii.RateFactor.Value) / 100)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!si.RecordedBillableFLSBrutto.HasValue)
|
||||
{
|
||||
si.RecordedBillableFLSNetto = si.InvoiceItems.Sum(ii => (ii.UnitCount ?? 0)); // * rf; //eigentlich falsch dass netto = brutto ist.
|
||||
si.RecordedBillableFLSBrutto = si.RecordedBillableFLSNetto;
|
||||
}
|
||||
si.AmountBillableTotal = totalAmount;
|
||||
si.AmountWithRateFactor = rateFactorAmount;
|
||||
|
||||
|
||||
//AdvancedPayments
|
||||
CalculateAdvancedPayments(si, c2s, null, null, hourlyRatesInSpanList);
|
||||
//EquityContribution (Eigenanteil)
|
||||
CalculateEquityContribution(si, c2s.SupportConcept, null, null);
|
||||
|
||||
si.Claim = si.AmountBillableTotal - (si.AmountAdvancedPayments ?? 0) - si.EquityContribution;
|
||||
}
|
||||
private decimal? CalculateApprovedTotalFLS(IList<ApprovalPeriod> apList)
|
||||
{
|
||||
decimal flsTotal = 0;
|
||||
foreach (var ap in apList)
|
||||
{
|
||||
flsTotal += ap.ApprovedTotal;
|
||||
}
|
||||
return flsTotal;
|
||||
}
|
||||
private decimal GetRateFactor(Settlement2DC si)
|
||||
{
|
||||
decimal rf = 1;
|
||||
if (si.RateFactor.HasValue && si.RateFactor.Value != 0)
|
||||
{
|
||||
rf = si.RateFactor.Value;
|
||||
rf = (100 + rf) / 100;
|
||||
}
|
||||
return rf;
|
||||
}
|
||||
// Abwesenheitsstunden werden hier auch in Berechnung ausgeklammert, Calc auch anpassen
|
||||
|
||||
public override bool ReduziereBetragBeiAbwesenheiten()
|
||||
{
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user