393 lines
14 KiB
C#
393 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Report.ReportObjects;
|
|
using BeWo.Service.Dienstplanung;
|
|
|
|
|
|
namespace SHKService
|
|
{
|
|
public class CustomMitarbeiterstundenkontoBerechnung : MitarbeiterstundenkontoBerechnung
|
|
{
|
|
private DateTime _BerichtsAnfang = DateTime.MinValue;
|
|
|
|
public override void CreateEmployeeDetails(MitarbeiterstundenkontoRO ro)
|
|
{
|
|
base.CreateEmployeeDetails(ro);
|
|
|
|
foreach (var ed in ro.EmployeeDetailList)
|
|
{
|
|
var c = ed.Employee.GetValidContractForDate(_BerichtsAnfang);
|
|
if (c != null)
|
|
{
|
|
ed.Custom14 = c.HourlyRate ?? 0;
|
|
ed.Custom15 = ed.Custom14 * Math.Round(ed.UeberstundenGesamt ?? 0, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void StarteBerechnung(DateTime berichtsAnfang, DateTime berichtsEnde, MitarbeiterstundenkontoRO.EmployeeDetail empDetail)
|
|
{
|
|
_BerichtsAnfang = berichtsAnfang;
|
|
this.vacationService.Bundesland = "Hessen";
|
|
AktuellBearbeitetesEmployeeDetail = empDetail;
|
|
}
|
|
|
|
public override bool AddServiceRecordToDuration(StundenkontoServiceRecord item)
|
|
{
|
|
if (item.ServiceDescription != null && item.ServiceDescription.Category != null)
|
|
{
|
|
if (item.ServiceDescription.Name != "Pause")
|
|
{
|
|
if (item.ServiceDescription.Category.Name == "Arbeitszeit")
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override void CorrectOverlappingTimes(IList<StundenkontoServiceRecord> serviceRecords)
|
|
{
|
|
base.CorrectOverlappingTimes(serviceRecords);
|
|
}
|
|
|
|
protected override bool HatArbeitszeitImZeitraum(IList<Arbeitszeit> arbeitszeiten, DateTime start, DateTime ende)
|
|
{
|
|
//return false;
|
|
return base.HatArbeitszeitImZeitraum(arbeitszeiten, start, ende);
|
|
}
|
|
|
|
protected override decimal? GetSollNachArbeitszeiten(Employee emp, DateTime start, DateTime ende)
|
|
{
|
|
if (BerechneSollNurBisZumAktuellenTag())
|
|
{
|
|
if (ende > DateTime.Now.Date.AddDays(1))
|
|
{
|
|
ende = DateTime.Now.Date.AddDays(1);
|
|
}
|
|
}
|
|
|
|
if (emp.Arbeitszeiten != null && emp.Arbeitszeiten.Count > 0)
|
|
{
|
|
if (HatArbeitszeitImZeitraum(emp.Arbeitszeiten, start, ende))
|
|
{
|
|
decimal soll = 0;
|
|
|
|
DateTime startTemp = start;
|
|
|
|
while (startTemp < ende)
|
|
{
|
|
soll += GetSollNachArbeitszeitenFuerTagCustom(emp, startTemp, false);
|
|
startTemp = startTemp.AddDays(1);
|
|
}
|
|
|
|
return soll;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private decimal GetSollNachArbeitszeitenFuerTagCustom(Employee emp, DateTime tag, bool beachteHalbeFeiertage)
|
|
{
|
|
var fak = GetFeiertagsFaktor(tag);
|
|
decimal soll = GetSollNachArbeitszeitenFuerTag(emp, tag);
|
|
|
|
|
|
if (fak > 0 && fak < 1 && !beachteHalbeFeiertage)
|
|
{
|
|
soll /= fak;
|
|
}
|
|
|
|
return soll;
|
|
}
|
|
|
|
protected override decimal GetSollNachArbeitszeitenFuerTag(Employee emp, DateTime tag)
|
|
{
|
|
//CB 14.01.2025: Wenn jemand Arbeitszeiten eingetragen hat, darf trotzdem nur das durschnittliche Soll für diesen Tag
|
|
//in das Gesamt Soll einfließen, egal wie die Uhrzeiten für diesen Arbeitstag definiert sind
|
|
|
|
if (tag.Day == 24 && tag.Month == 12 && tag.Year == 2025)
|
|
{
|
|
|
|
}
|
|
decimal soll = 0;
|
|
var fak = GetFeiertagsFaktor(tag);
|
|
|
|
if (BerechneFeiertageAlsArbeitszeit())
|
|
{
|
|
if (fak == 1)
|
|
{
|
|
fak = 0;
|
|
}
|
|
}
|
|
|
|
if (fak < 1)
|
|
{
|
|
soll = BerechneDurschnittlicheArbeitszeitenFuerTag(emp, tag) * (1 - fak);
|
|
}
|
|
|
|
return soll;
|
|
}
|
|
|
|
private decimal BerechneDurschnittlicheArbeitszeitenFuerTag(Employee emp, DateTime tag)
|
|
{
|
|
//CB 14.01.2025: Wenn jemand Arbeitszeiten eingetragen hat, darf trotzdem nur das durschnittliche Soll für diesen Tag
|
|
//in das Gesamt Soll einfließen, egal wie die Uhrzeiten für diesen Arbeitstag definiert sind
|
|
|
|
decimal stdGesamt = 0;
|
|
|
|
if (emp.Arbeitszeiten != null)
|
|
{
|
|
foreach (var az in emp.Arbeitszeiten)
|
|
{
|
|
if ((!az.GueltigVon.HasValue || az.GueltigVon.Value <= tag) &&
|
|
(!az.GueltigBis.HasValue || az.GueltigBis.Value >= tag))
|
|
{
|
|
var std = GetArbeitszeitStundenFuerTag(az, tag);
|
|
if (std > 0)
|
|
{
|
|
var c = emp.GetValidContractForDate(tag);
|
|
if (c != null && c.WeeklyTotalHours.HasValue && c.WeeklyDays.HasValue && c.WeeklyDays.Value > 0)
|
|
{
|
|
std = c.WeeklyTotalHours.Value / c.WeeklyDays.Value;
|
|
return std;
|
|
}
|
|
}
|
|
stdGesamt += std;
|
|
}
|
|
}
|
|
}
|
|
|
|
return stdGesamt;
|
|
}
|
|
|
|
protected override ServiceRecordSummary BerechneStunden(MitarbeiterstundenkontoRO.EmployeeDetail empDetail, IList<StundenkontoServiceRecord> groupFilteredRecords, DateTime berichtsAnfang,
|
|
DateTime berichtsEnde)
|
|
{
|
|
//base.CorrectOverlappingTimes(groupFilteredRecords.Where(s => s.ServiceDescription.Category.Name == "Arbeitszeit" && s.ServiceDescription.Name != "Pause").ToList());
|
|
|
|
decimal flsGesamt = 0;
|
|
decimal arbeitszeit = 0;
|
|
|
|
var sum = new ServiceRecordSummary();
|
|
sum.RecordsImBerichtszeitraum = new List<StundenkontoServiceRecord>();
|
|
//base.CorrectOverlappingTimes(groupFilteredRecords);
|
|
|
|
foreach (var item in groupFilteredRecords)
|
|
{
|
|
if (!IsServiceRecordFehlzeit(item))
|
|
{
|
|
if (item.Start >= berichtsAnfang && item.Start < berichtsEnde)
|
|
{
|
|
//if (AddServiceRecordToDuration(item))
|
|
//{
|
|
var duration = GetDuration(item, empDetail);
|
|
|
|
if (item.ServiceDescription != null &&
|
|
item.ServiceDescription.Category != null)
|
|
{
|
|
if (item.ServiceDescription.Category.Name == "Arbeitszeit" && item.ServiceDescription.Name != "Pause")
|
|
{
|
|
|
|
arbeitszeit += duration;
|
|
}
|
|
else if (item.ServiceDescription.Category.IsBillable)
|
|
{
|
|
flsGesamt += duration;
|
|
}
|
|
|
|
}
|
|
sum.RecordsImBerichtszeitraum.Add(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
sum.IstAbrechenbar = flsGesamt;
|
|
sum.IstNichtAbrechenbar = arbeitszeit - flsGesamt;
|
|
|
|
return sum;
|
|
}
|
|
|
|
public override MitarbeiterstundenkontoRO.EmployeeDetail BerechneUeberstundenBis(MitarbeiterstundenkontoRO.EmployeeDetail edOrig, IList<StundenkontoServiceRecord> records, DateTime monat, out decimal? ueberstunden,
|
|
out decimal alteExtraUeberstunden)
|
|
{
|
|
return base.BerechneUeberstundenBis(edOrig, records, monat, out ueberstunden, out alteExtraUeberstunden);
|
|
|
|
}
|
|
|
|
public override IList<MitarbeiterstundenkontoRO.DayDetail> CreateDayDetails(DateTime berichtStart, DateTime berichtEnde, MitarbeiterstundenkontoRO.EmployeeDetail ed, IList<StundenkontoServiceRecord> recordsAll)
|
|
{
|
|
var list = base.CreateDayDetails(berichtStart, berichtEnde, ed, recordsAll);
|
|
foreach (var dd in list)
|
|
{
|
|
dd.MinutesTotal = 0;
|
|
dd.SpecialHours = 0;
|
|
dd.PauseInMinuten = 0;
|
|
|
|
foreach (var sr in recordsAll)
|
|
{
|
|
if (sr.Start >= berichtStart && sr.Start < berichtEnde && sr.Start.Day == dd.Date.Day)
|
|
{
|
|
decimal duration = GetDuration(sr, ed);
|
|
|
|
if (sr.ServiceDescription.Name == "Pause")
|
|
{
|
|
dd.PauseInMinuten += duration;
|
|
|
|
}
|
|
else if (sr.ServiceDescription.Category.Name == "Arbeitszeit")
|
|
{
|
|
|
|
dd.MinutesTotal += duration;
|
|
|
|
}
|
|
else if (sr.ServiceDescription.Name != "Arbeitszeit" &&
|
|
sr.ServiceDescription.Category.IsBillable)
|
|
{
|
|
dd.SpecialHours += duration;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dd.PauseInMinuten > 0)
|
|
{
|
|
dd.MinutesTotal -= dd.PauseInMinuten;
|
|
if (dd.MinutesTotal < 0)
|
|
{
|
|
dd.MinutesTotal = 0;
|
|
}
|
|
}
|
|
|
|
if (dd.Date.Day == 24 && dd.Date.Month == 12 && dd.Date.Year == 2025)
|
|
{
|
|
|
|
}
|
|
if (dd.Feiertag != null && dd.SollStunden > 0)
|
|
{
|
|
dd.MinutesTotal += dd.SollStunden * 60;
|
|
}
|
|
|
|
if (dd.AbsenceTimes != null)
|
|
{
|
|
foreach (var at in dd.AbsenceTimes)
|
|
{
|
|
if (at.AbsenceReason.Description == "Krankengeld" || at.AbsenceReason.Description == "Unbezahlten Urlaub")
|
|
{
|
|
dd.Custom1 = "x"; // String.Format("{0:0.00}", ed.SollProTag * 60);
|
|
}
|
|
if (AbsenceTimeAufIstStundenAddieren(at))
|
|
{
|
|
dd.MinutesTotal = dd.SollStunden * 60;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
|
|
protected override decimal GetDuration(StundenkontoServiceRecord sr, MitarbeiterstundenkontoRO.EmployeeDetail ed)
|
|
{
|
|
var d = base.GetDuration(sr, ed);
|
|
|
|
if (sr.ServiceDescription.Category.Name == "Arbeitszeit" && sr.ServiceDescription.Name == "Zeitabzug")
|
|
{
|
|
d *= -1;
|
|
}
|
|
|
|
return d;
|
|
}
|
|
|
|
public override bool IstAnrechenbareAbsenceTime(AbsenceTime item)
|
|
{
|
|
if (item.AbsenceReason.Description == "Freizeitausgleich")
|
|
{
|
|
return false;
|
|
}
|
|
return base.IstAnrechenbareAbsenceTime(item);
|
|
}
|
|
|
|
public override bool IsKrankheitAbsenceTime(AbsenceTime absenceTime)
|
|
{
|
|
return !IsUrlaubAbsenceTime(absenceTime);
|
|
}
|
|
|
|
public override bool AbsenceTimeAufIstStundenAddieren(AbsenceTime at)
|
|
{
|
|
if (at.AbsenceReason.Description == "Mutterschutz")
|
|
{
|
|
return true;
|
|
}
|
|
return base.AbsenceTimeAufIstStundenAddieren(at);
|
|
}
|
|
|
|
public override bool SollPauseBerechnen()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override bool ShouldCreateDayDetails()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override MitarbeiterstundenkontoRO.DayDetail CreateDayDetail(DateTime date, MitarbeiterstundenkontoRO.EmployeeDetail ed)
|
|
{
|
|
var dd = base.CreateDayDetail(date, ed);
|
|
dd.MaxHoursUntilBreak = null;
|
|
dd.MaxHoursUntilBreak2 = null;
|
|
dd.BreakMinutes = null;
|
|
dd.BreakMinutes2 = null;
|
|
return dd;
|
|
}
|
|
|
|
public override decimal BerechnePauseMinuten(IList<StundenkontoServiceRecord> srListAlle)
|
|
{
|
|
var srList = srListAlle.Where(s => s.ServiceDescription.Category.Name == "Arbeitszeit");
|
|
decimal pausenZeit = 0;
|
|
|
|
List<StundenkontoServiceRecord> pausen = new List<StundenkontoServiceRecord>();
|
|
List<StundenkontoServiceRecord> nichtpausen = new List<StundenkontoServiceRecord>();
|
|
|
|
foreach (var sr in srList)
|
|
{
|
|
if (sr.ServiceDescription.Name == "Pause")
|
|
{
|
|
pausen.Add(sr);
|
|
}
|
|
else
|
|
{
|
|
nichtpausen.Add(sr);
|
|
}
|
|
}
|
|
|
|
foreach (var pause in pausen)
|
|
{
|
|
pausenZeit += pause.RoundedDuration;
|
|
}
|
|
return pausenZeit;
|
|
}
|
|
|
|
public override bool BerechneFeiertageAlsArbeitszeit()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override decimal GetFeiertagsFaktor(DateTime start)
|
|
{
|
|
if (start.Month == 12)
|
|
{
|
|
if (start.Day == 24 || start.Day == 31)
|
|
{
|
|
return 0.5m;
|
|
}
|
|
}
|
|
|
|
return base.GetFeiertagsFaktor(start);
|
|
}
|
|
}
|
|
} |