Files
BeWoPlaner/Service/Plugins/VacationService.cs
rene 28d271f86f Urlaubskonto Berechnung
Urlaubskonto Anzeige AbwesenheitsView
2020-10-13 14:35:06 +02:00

283 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
namespace BeWo.Service.Plugins
{
public class VacationService : AbstractIDSpecificDefaultClass<VacationService>
{
public virtual bool IstFeiertag(DateTime start)
{
List<DateTime> feiertage = GetFeiertage(start.Year);
foreach (var ft in feiertage)
{
if (start.Date == ft)
return true;
}
return false;
}
public virtual List<DateTime> GetFeiertage(int year)
{
var list = GetFeiertage(year, "NRW");
return list.Select(f => f.Datum).ToList();
}
public FeiertagDC GetFeiertag(DateTime start)
{
var feiertage = GetFeiertage(start.Year, "NRW");
foreach (var ft in feiertage)
{
if (start == ft.Datum)
return ft;
}
return null;
}
public FerienDC GetFerien(DateTime start, String bundesland)
{
var ferienList = GetFerien(bundesland);
foreach (var ferien in ferienList)
{
if (start >= ferien.Start && start <= ferien.Ende)
return ferien;
}
return null;
}
public virtual List<FeiertagDC> GetFeiertage(int year, String bundesland)
{
List<FeiertagDC> list = new List<FeiertagDC>();
list.Add(new FeiertagDC { Datum = new DateTime(year, 1, 1), Name = "Neujahr" });
//list.Add(new DateTime(year, 1, 6)); // , "Heilige Drei Könige"));
list.Add(new FeiertagDC { Datum = new DateTime(year, 5, 1), Name = "Tag der Arbeit" });
//list.Add(new DateTime(year, 8, 15)); // , "Mariä Himmelfahrt"));
list.Add(new FeiertagDC { Datum = new DateTime(year, 10, 3), Name = "Tag der dt. Einheit" });
//list.Add(new DateTime(year, 10, 31)); // , "Reformationstag"));
list.Add(new FeiertagDC { Datum = new DateTime(year, 11, 1), Name = "Allerheiligen " });
list.Add(new FeiertagDC { Datum = new DateTime(year, 12, 25), Name = "1. Weihnachtstag" });
list.Add(new FeiertagDC { Datum = new DateTime(year, 12, 26), Name = "2. Weihnachtstag" });
if (year == 2017)
{
list.Add(new FeiertagDC { Datum = new DateTime(year, 10, 31), Name = "Reformationstag" });
}
DateTime osterSonntag = GetOsterSonntag(year);
//list.Add(osterSonntag); // , "Ostersonntag"));
//list.Add(osterSonntag.AddDays(-3)); // , "Gründonnerstag")); q
//list.Add(osterSonntag.AddDays(-48)); // , "Rosenmontag"));
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(-2), Name = "Karfreitag" });
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(1), Name = "Ostermontag" });
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(39), Name = "Christi Himmelfahrt" });
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(50), Name = "Pfingstmontag" });
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(60), Name = "Fronleichnam" });
return list;
}
public static DateTime GetOsterSonntag(int year)
{
int g, h, c, j, l, i;
g = year % 19;
c = year / 100;
h = ((c - (c / 4)) - (((8 * c) + 13) / 25) + (19 * g) + 15) % 30;
i = h - (h / 28) * (1 - (29 / (h + 1)) * ((21 - g) / 11));
j = (year + (year / 4) + i + 2 - c + (c / 4)) % 7;
l = i - j;
int month = (int)(3 + ((l + 40) / 44));
int day = (int)(l + 28 - 31 * (month / 4));
return new DateTime(year, month, day);
}
public virtual List<FerienDC> GetFerien(String bundesland = "nrw")
{
List<FerienDC> list = new List<FerienDC>();
list.Add(new FerienDC() { Name = "Sommerferien 2014", Start = new DateTime(2014, 7, 7), Ende = new DateTime(2014, 8, 19) });
list.Add(new FerienDC() { Name = "Herbstferien 2014", Start = new DateTime(2014, 10, 6), Ende = new DateTime(2014, 10, 18) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2014", Start = new DateTime(2014, 12, 22), Ende = new DateTime(2015, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2015", Start = new DateTime(2015, 3, 30), Ende = new DateTime(2015, 4, 11) });
list.Add(new FerienDC() { Name = "Sommerferien 2015", Start = new DateTime(2015, 6, 29), Ende = new DateTime(2015, 8, 11) });
list.Add(new FerienDC() { Name = "Herbstferien 2015", Start = new DateTime(2015, 10, 5), Ende = new DateTime(2015, 10, 17) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2015", Start = new DateTime(2015, 12, 23), Ende = new DateTime(2016, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2016", Start = new DateTime(2016, 3, 21), Ende = new DateTime(2016, 4, 2) });
list.Add(new FerienDC() { Name = "Sommerferien 2016", Start = new DateTime(2016, 7, 11), Ende = new DateTime(2016, 8, 23) });
list.Add(new FerienDC() { Name = "Herbstferien 2016", Start = new DateTime(2016, 10, 10), Ende = new DateTime(2016, 10, 21) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2016", Start = new DateTime(2016, 12, 23), Ende = new DateTime(2017, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2017", Start = new DateTime(2017, 4, 10), Ende = new DateTime(2017, 4, 22) });
list.Add(new FerienDC() { Name = "Sommerferien 2017", Start = new DateTime(2017, 7, 17), Ende = new DateTime(2017, 8, 29) });
list.Add(new FerienDC() { Name = "Herbstferien 2017", Start = new DateTime(2017, 10, 23), Ende = new DateTime(2017, 11, 4) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2017", Start = new DateTime(2017, 12, 27), Ende = new DateTime(2018, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2018", Start = new DateTime(2018, 3, 26), Ende = new DateTime(2018, 4, 7) });
list.Add(new FerienDC() { Name = "Sommerferien 2018", Start = new DateTime(2018, 7, 16), Ende = new DateTime(2018, 8, 28) });
list.Add(new FerienDC() { Name = "Herbstferien 2018", Start = new DateTime(2018, 10, 15), Ende = new DateTime(2018, 10, 27) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2018", Start = new DateTime(2018, 12, 21), Ende = new DateTime(2019, 1, 4) });
list.Add(new FerienDC() { Name = "Osterferien 2019", Start = new DateTime(2019, 4, 15), Ende = new DateTime(2019, 4, 27) });
list.Add(new FerienDC() { Name = "Sommerferien 2019", Start = new DateTime(2019, 7, 15), Ende = new DateTime(2019, 8, 27) });
list.Add(new FerienDC() { Name = "Herbstferien 2019", Start = new DateTime(2019, 10, 14), Ende = new DateTime(2019, 10, 26) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2019", Start = new DateTime(2019, 12, 23), Ende = new DateTime(2020, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2020", Start = new DateTime(2020, 4, 6), Ende = new DateTime(2020, 4, 18) });
list.Add(new FerienDC() { Name = "Sommerferien 2020", Start = new DateTime(2020, 6, 29), Ende = new DateTime(2020, 8, 11) });
list.Add(new FerienDC() { Name = "Herbstferien 2020", Start = new DateTime(2020, 10, 12), Ende = new DateTime(2020, 10, 24) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2020", Start = new DateTime(2020, 12, 23), Ende = new DateTime(2021, 1, 6) });
return list;
}
public virtual List<long> GetVacationReasonIDs()
{
var res = new List<long>();
var filters = new List<string> { "URLAUB" };
var reasons = DAOFactory.GenericDAO.GetAllActive<AbsenceReason>();
foreach (var reason in reasons)
{
var desc = reason.Description.ToUpper();
foreach (var filter in filters)
{
if (desc.Contains(filter))
{
res.Add(reason.Oid.Value);
break;
}
}
}
return res;
}
public virtual DateTime GetExpirationDate(int year)
{
return new DateTime(year, 3, 31);
}
public virtual Dictionary<int, UrlaubskontoDC> BerechneUrlaubskonto(Employee emp, int year)
{
try
{
var absReason = GetVacationReasonIDs();
var absences = emp.AbsenceTimes.Where(x => absReason.Contains(x.AbsenceReason.Oid.Value) &&
(x.Start.HasValue && x.Start.Value.Year <= year))
//(!x.End.HasValue || x.End.Value.Year >= year)
.OrderBy(x => x.Start);
// Startzeitpunkt für Berechnung berechnen
var firstContractYear = emp.Contracts?.Min(x => x.EntryDate)?.Year ?? int.MaxValue;
var firstAbsenceTimeYear = absences.Min(x => x.Start)?.Year ?? int.MaxValue;
var firstYear = Math.Min(year, Math.Min(firstContractYear, firstAbsenceTimeYear));
// Urlaubskonten erzeugen
var konten = new Dictionary<int, UrlaubskontoDC>();
for (int i = firstYear; i <= year; i++)
{
konten.Add(i, new UrlaubskontoDC());
}
// Jahresurlaubanspruch berechnen
foreach (var contract in emp.Contracts)
{
var start = contract.EntryDate?.Year ?? firstYear;
var end = contract.ContractEndDate?.Year ?? year;
for (int i = start; i <= end; i++)
{
var tmp = konten[i];
tmp.Urlaubsanspruch += contract.LeaveDays ?? 0;
tmp.Resturlaub = tmp.Urlaubsanspruch;
}
}
// Abwesenheiten in Jahr x berücksichtigen
var absencesYear = new List<Tuple<int, AbsenceTime>>();
foreach (var abs in absences)
{
var till = Math.Min(abs.End?.Year ?? year, year);
for (int i = abs.Start.Value.Year; i <= till; i++)
{
absencesYear.Add(new Tuple<int, AbsenceTime>(i, abs));
}
}
// Urlaubsanspruch berechnen
var yearFiller = firstYear;
absencesYear = absencesYear.OrderBy(x => x.Item1).ToList();
foreach (var tuple in absencesYear)
{
var absYear = tuple.Item1;
var absence = tuple.Item2;
// Resturlaub Vorjahr übertragen
while (yearFiller < absYear)
{
var tmp = konten[yearFiller];
var tmp2 = konten[yearFiller + 1];
tmp2.ResturlaubVorjahrTotal = tmp.Resturlaub;
tmp2.ResturlaubVorjahr = tmp.Resturlaub;
yearFiller++;
}
var current = konten[absYear];
var start = DateTimeExtensions.GetMax(absence.Start, new DateTime(absYear, 1, 1));
var end = DateTimeExtensions.GetMin(absence.End, new DateTime(absYear, 12, 31));
var dauer = (decimal)(absence.End.Value - absence.Start.Value).Days + 1;
var expiration = GetExpirationDate(year);
// Resturlaub vom Vorjahr verwenden, wenn möglich
if (current.ResturlaubVorjahr > 0 && start <= expiration)
{
var firstEnd = (DateTime)DateTimeExtensions.GetMin(end, expiration);
var dauerVorjahr = (decimal)(firstEnd - absence.Start.Value).Days + 1;
var bucheVorjahr = Math.Min(current.ResturlaubVorjahr, dauerVorjahr);
current.ResturlaubVorjahr -= bucheVorjahr;
dauer -= bucheVorjahr;
}
// Restliche Dauer vom Urlaub abziehen
current.Resturlaub -= dauer;
}
return konten;
}
catch (Exception e)
{
throw e;
}
}
}
}