MH: Lebenshilfe Stade MID Stundenkonto

This commit is contained in:
2025-01-30 13:49:26 +01:00
parent 90b73ba5bd
commit 197b449912

View File

@@ -3,15 +3,333 @@ using System.Collections.Generic;
using System.Linq;
using BeWo.Data.Entities;
using BeWo.Report.ReportObjects;
using BS.Shared.Core;
namespace LebenshilfeStadeMID
{
public class CustomMitarbeiterstundenkontoBerechnung : MitarbeiterstundenkontoBerechnung
{
public override bool ShouldCreateDayDetails()
private const int ANZ_WOCHENTAGE = 5;
public override bool ShouldCreateDayDetails()
{
return true;
}
}
// Reguläres Soll nur mit Vertrag berechnen, auch wenn es Arbeitszeiten gibt
protected override decimal? GetSollNachArbeitszeiten(Employee emp, DateTime start, DateTime ende)
{
return null;
}
// SollProTag für Abwesenheiten mit Vertrag berechnen, auch wenn es Arbeitszeiten gibt
public override AbsenceTimeDays GetAbsenceTimeDaysWithWorkWeeks(Employee emp, DateTime start, DateTime end, int arbeitstageProWoche)
{
return GetAbsenceTimeDaysWithWorkWeeks(emp.AbsenceTimes, start, end, arbeitstageProWoche);
}
// SollProTag für Abwesenheiten mit Vertrag berechnen, auch wenn es Arbeitszeiten gibt
public override decimal BerechneStundenDurchAbwesenheiten(AbsenceTimeDays ath, DateTime start, DateTime ende, Contract c, MitarbeiterstundenkontoRO.EmployeeDetail ed)
{
#region Standardkram
if (BerechneAlteAbwesenheitsStunden(start))
{
return BerechneStundenDurchAbwesenheitenAlt(ath, start, ende, c, ed);
}
//if (ath.StundenGesamt.HasValue)
//{
// return ath.StundenGesamt.Value;
//}
#endregion
decimal stunden = 0;
if (c != null)
{
if (ath.TageGesamt.HasValue)
{
// hier würden eigentlich die Arbeitszeiten bedacht werden, das soll aber nicht passieren, daher ist der Code weg
//if (HatArbeitszeitImZeitraum(ed.Employee.Arbeitszeiten, start, ende))
//{
// return BerechneAbwesenheitsStundenDurchArbeitszeiten(ed.Employee, start, ende);
//}
#region Standardkram
decimal sollStundenProWoche = BerechneSollProWoche(c, ed);
if (sollStundenProWoche > 0)
{
if (ed.ArbeitstageProWoche == 5)
{
stunden = ath.TageGesamt.Value * (sollStundenProWoche / 5);
}
else if (ath.TageProWocheDict != null && ed.ArbeitstageProWoche > 0)
{
foreach (var week in ath.TageProWocheDict.Keys)
{
var tage = ath.TageProWocheDict[week];
if (tage > 0)
{
if (tage > ed.ArbeitstageProWoche)
{
tage = ed.ArbeitstageProWoche;
}
stunden += tage * (sollStundenProWoche / ed.ArbeitstageProWoche);
}
}
}
}
#endregion
}
}
return stunden;
}
// hier wird mittendrin auf die Arbeitszeiten geprüft, das muss raus. Ganzer Rest ist Standard, ging aber nicht ohne alles zu kopieren..
public override void CalculateAbsenceTimesForDay(MitarbeiterstundenkontoRO.DayDetail dd, MitarbeiterstundenkontoRO.EmployeeDetail ed)
{
#region Standardkram
var absenceTimes = ed.Employee.AbsenceTimes;
if (absenceTimes != null)
{
foreach (var absenceTime in absenceTimes)
{
//if (IsUrlaubAbsenceTime(absenceTime) || IsKrankheitAbsenceTime(absenceTime))
//{
DateTimeSpan span = new DateTimeSpan();
span.StartDate = dd.Date;
if (absenceTime.Start.HasValue && absenceTime.Start.Value > span.StartDate)
{
span.StartDate = absenceTime.Start.Value;
}
if (absenceTime.End.HasValue && absenceTime.End.Value.Date == span.StartDate.Date &&
absenceTime.End.Value.Hour > 0)
{
span.EndDate = absenceTime.End.Value;
}
else
{
span.EndDate = dd.Date.AddDays(1);
if (absenceTime.End.HasValue && absenceTime.End.Value.Date.AddDays(1) < span.EndDate)
{
span.EndDate = absenceTime.End.Value.Date.AddDays(1);
}
}
if (span.EndDate > dd.Date && span.StartDate < dd.Date.AddDays(1))
{
DateTime day = span.StartDate;
var faktor = GetFeiertagsFaktor(day);
if (faktor < 1 && (day.DayOfWeek != DayOfWeek.Saturday || ed.ArbeitstageProWoche == 6) && (day.DayOfWeek != DayOfWeek.Sunday || ed.ArbeitstageProWoche > 6)) // Prüfung auf 6 + bzw 7 Tage Woche
{
//Berechne Soll, entweder aus Vertrag oder Arbeitszeiten
var sollDiesenTag = ed.SollProTag;
bool checkMaxWochenSoll = true;
if (!IstAnrechenbareAbsenceTime(absenceTime))
{
sollDiesenTag = 0;
}
#endregion
// Prüfung für Arbeitszeiten raus, das ist alles, was hier anders gemacht ist als im Standard
// else if (HatArbeitszeitImZeitraum(ed.Employee.Arbeitszeiten, dd.Date, dd.Date))
//{
// sollDiesenTag = BerechneAlleAbwesenheitsStundenFuerArbeitszeiten(ed.Employee, dd.Date); // Hier wird der Feiertagsfaktor schon applied
//}
#region Standardkram
else
{
var ssa = GetSollStundenForAbsenceTime(ed, absenceTime, dd.Date);
if (ssa.HasValue)
{
sollDiesenTag = ssa.Value;
checkMaxWochenSoll = false;
}
else
{
var c = ed.Employee.GetValidContractForDate(dd.Date);
if (c != null)
{
decimal wth = 0;
int apw = ANZ_WOCHENTAGE;
if (c.WeeklyTotalHours.HasValue)
{
wth = c.WeeklyTotalHours.Value;
}
if (c.WeeklyDays.HasValue && c.WeeklyDays.Value > 0)
{
apw = c.WeeklyDays.Value;
}
sollDiesenTag = wth / apw;
}
}
}
//Dauer der Abwesenheit = Soll an diesem Tag
bool istGanztaegig = true;
var abwesenheitsDauer = sollDiesenTag;
if (span.StartDate.Hour > 0 && span.EndDate.Hour > 0)
{
istGanztaegig = false;
var ts = span.EndDate.Subtract(span.StartDate);
abwesenheitsDauer = (decimal)ts.TotalHours;
if (SchneideZuvieleAbwesenheitsstundenAb() && abwesenheitsDauer > sollDiesenTag)
{
abwesenheitsDauer = sollDiesenTag;
}
sollDiesenTag -= abwesenheitsDauer;
if (sollDiesenTag < 0)
{
sollDiesenTag = 0;
}
faktor = 1; // Keine halben Feiertag berücksichtigen, wenn die Abwesenheit in Stunden angegeben wurde
}
if (faktor != 0 && !HatArbeitszeitImZeitraum(ed.Employee.Arbeitszeiten, dd.Date, dd.Date))
{
abwesenheitsDauer *= faktor; //halbe Feiertage etc. berücksichtigen
}
if (ed.AbsenceTimeDays != null && ed.AbsenceTimeDays.TageProWocheDict != null)
{
if (ed.AbsenceTimeDays.RestStundenProWocheDict == null)
{
ed.AbsenceTimeDays.RestStundenProWocheDict = new Dictionary<DateTimeSpan, decimal>();
}
foreach (var week in ed.AbsenceTimeDays.TageProWocheDict.Keys)
{
if (!ed.AbsenceTimeDays.RestStundenProWocheDict.ContainsKey(week))
{
ed.AbsenceTimeDays.RestStundenProWocheDict.Add(week, ed.SollProWoche);
}
if (day.Date >= week.StartDate && day.Date <= week.EndDate && checkMaxWochenSoll)
{
var rest = ed.AbsenceTimeDays.RestStundenProWocheDict[week];
if (rest < abwesenheitsDauer)
{
abwesenheitsDauer = rest;
}
rest -= abwesenheitsDauer;
if (rest < 0)
{
rest = 0;
}
ed.AbsenceTimeDays.RestStundenProWocheDict[week] = rest;
}
}
}
if (!AbsenceTimeAufIstStundenAddieren(absenceTime) && IsUrlaubAbsenceTime(absenceTime))
{ // Vermutlich diese Methode in CustomMitarbeiterStundenKontoBerechnung überschreiben und hier Prüfung machen, ob absenceReason ohne Fortzahlung ist
//und wenn ja, HoursSick oder Soll oder so für den Tag auf 0 setzen
dd.HoursInVacation = abwesenheitsDauer;
var tspan = TimeSpan.FromHours((double)abwesenheitsDauer);
dd.TimeInVacation = String.Format("{0:00}:{1:00}", tspan.Hours, tspan.Minutes);
}
else if (!AbsenceTimeAufIstStundenAddieren(absenceTime) && IsKrankheitAbsenceTime(absenceTime))
{
dd.HoursSick = abwesenheitsDauer;
var tspan = TimeSpan.FromHours((double)abwesenheitsDauer);
dd.TimeSick = String.Format("{0:00}:{1:00}", tspan.Hours, tspan.Minutes);
}
else
{
if (!AbsenceTimeAufIstStundenAddieren(absenceTime))
{
dd.HoursOtherAbsenceTimes = abwesenheitsDauer;
var tspan = TimeSpan.FromHours((double)abwesenheitsDauer);
dd.TimeOtherAbsenceTimes = String.Format("{0:00}:{1:00}", tspan.Hours, tspan.Minutes);
}
if (istGanztaegig)
{
//Bei ganztägigen Abwesenheiten darf nicht noch zusätzlich gearbeitet werden
dd.MinutesTotal = 0;
dd.TimeTotal = "00:00";
}
dd.MinutesTotal += abwesenheitsDauer * 60;
TimeSpan tspan2 = TimeSpan.FromMinutes((double)dd.MinutesTotal);
dd.TimeTotal = String.Format("{0:00}:{1:00}", tspan2.Hours, tspan2.Minutes);
}
if (dd.AbsenceTimes == null)
{
dd.AbsenceTimes = new List<AbsenceTime>();
}
dd.AbsenceTimes.Add(absenceTime);
//dd.MinutesTotal += sollDiesenTag * 60;
}
}
}
}
#endregion
}
// Nur bis 2018
private decimal BerechneStundenDurchAbwesenheitenAlt(AbsenceTimeDays ath, DateTime start, DateTime ende, Contract c, MitarbeiterstundenkontoRO.EmployeeDetail ed)
{
decimal? sollProMonat = BerechneSollProMonat(ed.Employee, start, ende);
if (sollProMonat.HasValue)
{
decimal stundenProTag = sollProMonat.Value / ed.ArbeitstageImBerichtszeitraum;
return (ath.TageGesamt.Value * stundenProTag);
}
else
{
decimal sollProWoche = BerechneSollProWoche(c, ed);
decimal stunden = 0;
if (ath.TageGesamt.HasValue)
{
if (ed.ArbeitstageProWoche == 5)
{
stunden = ath.TageGesamt.Value * (sollProWoche / ed.ArbeitstageProWoche);
}
else if (ath.TageProWocheDict != null && ed.ArbeitstageProWoche > 0)
{
foreach (var week in ath.TageProWocheDict.Keys)
{
var tage = ath.TageProWocheDict[week];
if (tage > 0)
{
if (tage > ed.ArbeitstageProWoche)
{
tage = ed.ArbeitstageProWoche;
}
stunden += tage * (sollProWoche / ed.ArbeitstageProWoche);
}
}
}
}
return stunden;
}
}
}
}