299 lines
14 KiB
C#
299 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Service.DCEntityMapper;
|
|
using BeWo.Service.Plugins;
|
|
using BS.Shared;
|
|
using BS.Shared.Core;
|
|
using BS.Shared.DataContracts;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Services;
|
|
|
|
namespace BeWo.Service.Invoicing
|
|
{
|
|
public class LWLDiggaBerechnung : AbstractIDSpecificDefaultClass<LWLDiggaBerechnung>
|
|
{
|
|
public virtual DateTime? Umstellungsdatum()
|
|
{
|
|
// letzter Tag mit alter Rundung (Variante 1) in Zeitervassung
|
|
return null;
|
|
}
|
|
|
|
public virtual bool EndRundung()
|
|
{
|
|
// ursprünglich ist vom LWL angedacht gewesen, dass nur Rundungsvariante 2 erlaubt ist,
|
|
// das heißt, dass die Rundung vom Zeiterfassungseintrag zum Monatsgesamtwert wechselt in dem Moment, wo die digitalen Belege genutzt werden
|
|
return true;
|
|
}
|
|
|
|
public DateTime BewilligtStart { get; set; }
|
|
public DateTime BewilligtEnde { get; set; }
|
|
public List<EntgeltzeitraumDigga> Entgeltzeitraeume { get; set; }
|
|
public List<BudgetnachweisDiggaMonatsZeile> MonatsZeilen { get; set; }
|
|
public decimal RateFactor { get; set; }
|
|
public decimal SummeFLMinuten { get; set; }
|
|
public decimal SummeFaktorMinuten { get; set; }
|
|
public decimal SummeGesamtMinuten { get; set; }
|
|
public decimal SummeFLStunden { get; set; }
|
|
public decimal SummeFehlkontakte { get; set; }
|
|
public decimal SummeFehlkontakteStunden { get; set; }
|
|
public decimal SummeFaktorStunden { get; set; }
|
|
public decimal SummeGesamtStunden { get; set; }
|
|
public decimal SummeGesamtStundenMitFK { get; set; }
|
|
|
|
public virtual void CreateLWLDiggaBerechnung(Settlement2DC si, CostBearer2SupportConcept cb2sc, DateTime? BewilligtStart, DateTime? BewilligtEnde)
|
|
{
|
|
var calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
|
|
var serviceRecords = GetBillableServiceRecords(cb2sc);
|
|
var relDC = cb2sc.MapToNewDC();
|
|
this.BewilligtStart = si.AccountingPeriodStart.Value;
|
|
this.BewilligtEnde = si.AccountingPeriodEnd.Value;
|
|
MonatsZeilen = new List<BudgetnachweisDiggaMonatsZeile>();
|
|
Entgeltzeitraeume = new List<EntgeltzeitraumDigga>();
|
|
CreateEntgeltzeitraeume(Entgeltzeitraeume, cb2sc, this.BewilligtStart, this.BewilligtEnde);
|
|
|
|
var span = new DateTimeSpan();
|
|
span.StartDateTime = si.AccountingPeriodStart.Value;
|
|
span.EndDateTime = si.AccountingPeriodEnd.Value.AddDays(1).AddTicks(-1);
|
|
Dictionary<string, BudgetnachweisDiggaMonatsZeile> monat2Zeile = new Dictionary<string, BudgetnachweisDiggaMonatsZeile>();
|
|
DateTime monat = new DateTime(this.BewilligtStart.Year, this.BewilligtStart.Month, this.BewilligtStart.Day);
|
|
|
|
CalculateMonatsbasisWerte(Entgeltzeitraeume, cb2sc, serviceRecords, span, monat2Zeile, monat);
|
|
|
|
CalculateMonatsMinutenWerteMitRundung(MonatsZeilen);
|
|
|
|
foreach (var e in this.Entgeltzeitraeume)
|
|
{
|
|
e.SummeFaktorStunden = Math.Round(e.SummeFaktorMinuten / 60, 2, MidpointRounding.AwayFromZero);
|
|
Math.Round(e.SummeFehlkontakteGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
e.SummeGesamtStunden = Math.Round(e.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
e.SummeGesamtStundenMitFK = e.SummeFehlkontakteStunden + e.SummeGesamtStunden;
|
|
|
|
SummeFLMinuten += e.SummeFLMinuten;
|
|
SummeFaktorMinuten += e.SummeFaktorMinuten;
|
|
SummeGesamtMinuten += e.SummeMinutenGerundet;
|
|
SummeFLStunden += e.SummeFLStunden;
|
|
SummeFaktorStunden += e.SummeFaktorStunden;
|
|
SummeGesamtStunden += e.SummeGesamtStunden;
|
|
SummeFehlkontakte += e.SummeFehlkontakte;
|
|
SummeFehlkontakteStunden += e.SummeFehlkontakteStunden;
|
|
SummeGesamtStundenMitFK += e.SummeGesamtStundenMitFK;
|
|
}
|
|
}
|
|
|
|
public virtual IList<ServiceRecord> GetBillableServiceRecords(CostBearer2SupportConcept c2s)
|
|
{
|
|
return c2s.ServiceRecords.Where(IsServiceRecordBillable).OrderBy(s => s.Start).ToList();
|
|
}
|
|
|
|
public virtual bool IsServiceRecordBillable(ServiceRecord iRecord)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
private void CalculateMonatsMinutenWerteMitRundung(List<BudgetnachweisDiggaMonatsZeile> MonatsZeilen)
|
|
{
|
|
DateTime? uDate = Umstellungsdatum();
|
|
bool neueRundung = EndRundung();
|
|
|
|
foreach (var mz in MonatsZeilen)
|
|
{
|
|
if (!uDate.HasValue || uDate.HasValue && mz.Monat > uDate)
|
|
{
|
|
mz.SummeMinutenGerundet = Math.Ceiling((mz.SummeFLMinuten + mz.SummeFLMinuten * 0.2m) / 10) * 10;
|
|
mz.SummeFLStunden = Math.Round(mz.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
mz.SummeFaktorMinuten = mz.SummeMinutenGerundet - mz.SummeFLMinuten;
|
|
mz.SummeFehlkontakteStunden = Math.Round(mz.SummeFehlkontakte / 60, 2, MidpointRounding.AwayFromZero);
|
|
mz.SummeGesamtMinutenMitFKGerundet = mz.SummeMinutenGerundet + mz.SummeFehlkontakte;
|
|
mz.SummeGesamtStundenMitFKGerundet = Math.Round(mz.SummeGesamtMinutenMitFKGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
else
|
|
{
|
|
mz.SummeFaktorMinuten = Math.Round(mz.SummeFLMinuten * 0.2m, 2, MidpointRounding.AwayFromZero);
|
|
mz.SummeMinutenGerundet = mz.SummeFLMinuten + SummeFaktorMinuten;
|
|
mz.SummeFLStunden = Math.Round(mz.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
mz.SummeFehlkontakteStunden = Math.Round(mz.SummeFehlkontakte / 60, 2, MidpointRounding.AwayFromZero);
|
|
mz.SummeGesamtMinutenMitFKGerundet = mz.SummeMinutenGerundet + mz.SummeFehlkontakte;
|
|
mz.SummeGesamtStundenMitFKGerundet = Math.Round(mz.SummeGesamtMinutenMitFKGerundet / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
|
|
foreach (var e in Entgeltzeitraeume)
|
|
{
|
|
if (e.Index == mz.Entgeltzeitraum)
|
|
{
|
|
e.ServiceRecords.AddRange(mz.ServiceRecords);
|
|
e.SummeFLMinuten += mz.SummeFLMinuten;
|
|
e.SummeFaktorMinuten += mz.SummeFaktorMinuten;
|
|
e.SummeMinutenGerundet += mz.SummeMinutenGerundet;
|
|
e.SummeFLStunden += mz.SummeFLStunden;
|
|
e.SummeFehlkontakte += mz.SummeFehlkontakte;
|
|
e.SummeFehlkontakteStunden += mz.SummeFehlkontakteStunden;
|
|
e.SummeGesamtStundenMitFK += mz.SummeGesamtStundenMitFKGerundet;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void CreateEntgeltzeitraeume(List<EntgeltzeitraumDigga> entgeltzeitraeume, CostBearer2SupportConcept cb2sc, DateTime bewilligtStart, DateTime bewilligtEnde)
|
|
{
|
|
var crList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(cb2sc.CostBearer.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.HourlyRate));
|
|
var crRfList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(cb2sc.CostBearer.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.RateFactor));
|
|
var rf = crRfList.GetCostRatePeriodForDate(CostRatePeriodType.RateFactor, this.BewilligtEnde);
|
|
if (rf != null && rf.CostRateValue.HasValue)
|
|
{
|
|
this.RateFactor = rf.CostRateValue.Value;
|
|
}
|
|
|
|
foreach (var cr in crList)
|
|
{
|
|
if (!cr.EndDate.HasValue)
|
|
{
|
|
cr.EndDate = this.BewilligtEnde.AddDays(1);
|
|
}
|
|
}
|
|
|
|
crList = crList.OrderBy(c => c.EndDate).ToList();
|
|
DateTime start = DateTime.MinValue;
|
|
int idx = 1;
|
|
foreach (var cr in crList)
|
|
{
|
|
if (!cr.StartDate.HasValue)
|
|
{
|
|
cr.StartDate = start;
|
|
}
|
|
if (cr.StartDate > DateTime.MinValue)
|
|
{
|
|
cr.StartDate = cr.StartDate.Value.AddDays(1);
|
|
}
|
|
if (cr.EndDate >= this.BewilligtStart && cr.StartDate <= this.BewilligtEnde)
|
|
{
|
|
var ez = new EntgeltzeitraumDigga();
|
|
ez.Index = idx++;
|
|
ez.Start = cr.StartDate.Value;
|
|
ez.Ende = cr.EndDate.Value;
|
|
|
|
if (ez.Start == DateTime.MinValue || ez.Start < BewilligtStart)
|
|
{
|
|
ez.Start = this.BewilligtStart;
|
|
}
|
|
if (ez.Ende == DateTime.MaxValue)
|
|
{
|
|
ez.Ende = this.BewilligtEnde;
|
|
}
|
|
|
|
ez.CostRatePeriod = cr;
|
|
ez.ServiceRecords = new List<ServiceRecordDC>();
|
|
ez.RateFactor = 0.20m; // Variabel setzen
|
|
Entgeltzeitraeume.Add(ez);
|
|
}
|
|
|
|
start = cr.EndDate.Value;
|
|
}
|
|
}
|
|
|
|
|
|
public virtual void CalculateMonatsbasisWerte(List<EntgeltzeitraumDigga> entgeltzeitraeume, CostBearer2SupportConcept cb2sc, IList<ServiceRecord> serviceRecords, DateTimeSpan span, Dictionary<string, BudgetnachweisDiggaMonatsZeile> monat2Zeile, DateTime monat)
|
|
{
|
|
while (monat <= this.BewilligtEnde)
|
|
{
|
|
String key = String.Format("{0:MM.yyyy}", monat);
|
|
var zeile = new BudgetnachweisDiggaMonatsZeile();
|
|
zeile.ServiceRecords = new List<ServiceRecordDC>();
|
|
zeile.Monat = monat;
|
|
zeile.SummeFLMinuten = 0;
|
|
zeile.SummeFehlkontakte = 0;
|
|
zeile.SummeGesamtMinutenMitFKGerundet = 0;
|
|
zeile.SummeGesamtStundenMitFKGerundet = 0;
|
|
|
|
foreach (var e in Entgeltzeitraeume)
|
|
{
|
|
if (e.Start <= monat && monat <= e.Ende)
|
|
{
|
|
zeile.Entgeltzeitraum = e.Index;
|
|
}
|
|
}
|
|
|
|
if (monat.Day != 1)
|
|
{
|
|
monat = new DateTime(monat.Year, monat.Month, 1);
|
|
}
|
|
monat = monat.AddMonths(1);
|
|
monat2Zeile.Add(key, zeile);
|
|
}
|
|
|
|
var groupBookingDict = new Dictionary<long, bool>();
|
|
foreach (var sr in serviceRecords)
|
|
{
|
|
if (sr.ServiceDescription.ServiceCategory.IsBillable && (!sr.GroupOid.HasValue || !groupBookingDict.ContainsKey(sr.GroupOid.Value)))
|
|
{
|
|
if (sr.GroupOid.HasValue)
|
|
{
|
|
groupBookingDict.Add(sr.GroupOid.Value, true);
|
|
}
|
|
var srDc = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(sr);
|
|
String key = String.Format("{0:MM.yyyy}", sr.Start);
|
|
|
|
if (monat2Zeile.ContainsKey(key))
|
|
{
|
|
if (monat2Zeile[key].Monat <= sr.Start.Value.Date)
|
|
{
|
|
monat2Zeile[key].ServiceRecords.Add(srDc);
|
|
decimal minuten = sr.RoundedDuration; // Check this
|
|
decimal prozent = sr.ServiceDescription.ServiceCategory.ProzentAbrechnung;
|
|
if (sr.ServiceDescription.Name.ToLower().Contains("fehlkontakt"))
|
|
{
|
|
monat2Zeile[key].SummeFehlkontakte += minuten;
|
|
}
|
|
else
|
|
{
|
|
monat2Zeile[key].SummeFLMinuten += minuten;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
MonatsZeilen.AddRange(monat2Zeile.Values.OrderBy(m => m.Monat));
|
|
}
|
|
}
|
|
|
|
public class BudgetnachweisDiggaMonatsZeile
|
|
{
|
|
public List<ServiceRecordDC> ServiceRecords { get; set; }
|
|
public DateTime Monat { get; set; }
|
|
public decimal SummeFLMinuten { get; set; }
|
|
public decimal SummeFaktorMinuten { get; set; }
|
|
public decimal SummeMinutenGerundet { get; set; }
|
|
public decimal SummeFLStunden { get; set; }
|
|
public decimal SummeFehlkontakte { get; set; }
|
|
public decimal SummeFehlkontakteStunden { get; set; }
|
|
public decimal SummeGesamtMinutenMitFKGerundet { get; set; }
|
|
public decimal SummeGesamtStundenMitFKGerundet { get; set; }
|
|
public int Entgeltzeitraum { get; set; }
|
|
public decimal? Betrag { get; set; }
|
|
|
|
}
|
|
|
|
public class EntgeltzeitraumDigga
|
|
{
|
|
public List<ServiceRecordDC> ServiceRecords { get; set; }
|
|
public CostRatePeriodDC CostRatePeriod { get; set; }
|
|
public DateTime Start { get; set; }
|
|
public DateTime Ende { get; set; }
|
|
public decimal RateFactor { get; set; }
|
|
public decimal SummeFLMinuten { get; set; }
|
|
public decimal SummeFaktorMinuten { get; set; }
|
|
public decimal SummeMinutenGerundet { get; set; }
|
|
public decimal SummeFLStunden { get; set; }
|
|
public decimal SummeFehlkontakte { get; set; }
|
|
public decimal SummeFehlkontakteGerundet { get; set; }
|
|
public decimal SummeFehlkontakteStunden { get; set; }
|
|
public decimal SummeFaktorStunden { get; set; }
|
|
public decimal SummeGesamtStunden { get; set; }
|
|
public decimal SummeGesamtStundenMitFK { get; set; }
|
|
public int Index { get; set; }
|
|
}
|
|
}
|