Files
BeWoPlaner/Service/Plugins/VacationService.cs

754 lines
37 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 BeWo.Service.ServiceImplementations;
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>();
if (bundesland.ToLower() == "nrw")
{
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, 21), Ende = new DateTime(2021, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2021", Start = new DateTime(2021, 3, 29), Ende = new DateTime(2021, 4, 10) });
list.Add(new FerienDC() { Name = "Sommerferien 2021", Start = new DateTime(2021, 7, 5), Ende = new DateTime(2021, 8, 17) });
list.Add(new FerienDC() { Name = "Herbstferien 2021", Start = new DateTime(2021, 10, 11), Ende = new DateTime(2021, 10, 23) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2021", Start = new DateTime(2021, 12, 24), Ende = new DateTime(2022, 1, 8) });
list.Add(new FerienDC() { Name = "Osterferien 2022", Start = new DateTime(2022, 4, 11), Ende = new DateTime(2022, 4, 23) });
list.Add(new FerienDC() { Name = "Sommerferien 2022", Start = new DateTime(2022, 6, 27), Ende = new DateTime(2022, 8, 9) });
list.Add(new FerienDC() { Name = "Herbstferien 2022", Start = new DateTime(2022, 10, 4), Ende = new DateTime(2022, 10, 15) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2022", Start = new DateTime(2022, 12, 23), Ende = new DateTime(2023, 1, 6) });
list.Add(new FerienDC() { Name = "Osterferien 2023", Start = new DateTime(2023, 4, 3), Ende = new DateTime(2023, 4, 15) });
list.Add(new FerienDC() { Name = "Sommerferien 2023", Start = new DateTime(2023, 6, 22), Ende = new DateTime(2023, 8, 4) });
list.Add(new FerienDC() { Name = "Herbstferien 2023", Start = new DateTime(2023, 10, 2), Ende = new DateTime(2023, 10, 14) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2023", Start = new DateTime(2023, 12, 21), Ende = new DateTime(2024, 1, 5) });
}
else if (bundesland.ToLower() == "niedersachsen")
{
list.Add(new FerienDC() { Name = "Weihnachtsferien 2020", Start = new DateTime(2020, 12, 21), Ende = new DateTime(2021, 1, 8) });
list.Add(new FerienDC() { Name = "Osterferien 2021", Start = new DateTime(2021, 3, 29), Ende = new DateTime(2021, 4, 09) });
list.Add(new FerienDC() { Name = "Sommerferien 2021", Start = new DateTime(2021, 7, 22), Ende = new DateTime(2021, 9, 1) });
list.Add(new FerienDC() { Name = "Herbstferien 2021", Start = new DateTime(2021, 10, 18), Ende = new DateTime(2021, 10, 29) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2021", Start = new DateTime(2021, 12, 23), Ende = new DateTime(2022, 1, 7) });
}
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 List<UrlaubskontoDarstellungDC> BerechneUrlaubskontoZurDarstellung(EmployeeDC emp, int year)
{
List<UrlaubskontoDarstellungDC> dcs = new List<UrlaubskontoDarstellungDC>();
EmployeeServiceImp es = new EmployeeServiceImp();
// Benötigt werden:
// Vetragliche Urlaubstage für´s Jahr
ContractDC contract = null;
foreach (var c in emp.Contracts) // Vertrag für Jahr raussuchen
{
DateTime contractEndDate = new DateTime();
if (c.ContractEndDate == null)
contractEndDate = new DateTime(2099, 12, 31);
else
contractEndDate = c.ContractEndDate.Value;
if (year >= c.EntryDate.Value.Year && year <= contractEndDate.Year)
{
contract = c;
break;
}
}
if (contract == null) // Kein Vertrag = kein Urlaubskonto
return null;
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = "Urlaubstage im Jahr " + year + ":",
AnzahlTage = contract.EmploymentType.LeaveDays == null ? string.Format("{0:0.00}", (decimal)contract.LeaveDays) : string.Format("{0:0.00}", (decimal)contract.EmploymentType.LeaveDays),
Herkunft = string.Format("EmpOid:{0} ContractOid:{1}", emp.EmployeeOid, contract.ContractOid),
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = null
});
// Geschenkte Urlaubstage im Jahr
var geschenkteUrlaubstage = es.GetGeschenkteUrlaubstageForEmployee((long)emp.EmployeeOid);
if (geschenkteUrlaubstage.Count > 0 && geschenkteUrlaubstage.Any(g => g.Date.Year == year))
{
//Gesamtanzahl der gesch. Urlaubstage fürs Jahr summieren
//decimal summeGeschenkteUrlaubstage = 0;
//foreach (var tage in geschenkteUrlaubstage)
//{
// if (tage.Date.Year == year)
// summeGeschenkteUrlaubstage += tage.AnzahlTage;
//}
//dcs.Add(new UrlaubskontoDarstellungDC()
//{
// Erlaeuterung = "Inkl. geschenkte Urlaubstage",
// AnzahlTage = contract.EmploymentType.LeaveDays == null ? (decimal)contract.LeaveDays + summeGeschenkteUrlaubstage : (decimal)contract.EmploymentType.LeaveDays + summeGeschenkteUrlaubstage,
// Herkunft = "GeschenkteUrlaubstageEmployeeOid" + emp.EmployeeOid,
// Tooltip = null,
// IsDeletable = false,
// DatumZurSortierung = null
//});
// Einen Eintrag pro Geschenktem Urlaubstag
foreach (var eintrag in geschenkteUrlaubstage)
{
if (eintrag.Date.Year == year)
{
var tempDate = eintrag.Date.ToString().Split(' ');
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = string.Format("Tage geschenkt am {0} von {1}", tempDate[0], eintrag.InsUser),
AnzahlTage = string.Format("+{0:0.00}", eintrag.AnzahlTage),
Herkunft = string.Format("GeschenkterUrlaubstagOid:{0}", eintrag.GeschenkterUrlaubstagOid),
Tooltip = eintrag.GeschenkterUrlaubstagNotice,
IsDeletable = true,
DatumZurSortierung = eintrag.Date
});
}
}
}
// Alle Urlaube, die Anfang oder Ende im gewählten Jahr haben
var absReason = GetVacationReasonIDs();
var absences = emp.AbsenceTimes.Where(x => absReason.Contains(x.Reason.AbsenceReasonOid.Value) && (x.Start.HasValue && x.Start.Value.Year == year)
|| absReason.Contains(x.Reason.AbsenceReasonOid.Value) && (x.End.HasValue && x.End.Value.Year == year))
.OrderBy(x => x.Start);
// Verfallener Resturlaub
var ent = DAOFactory.GenericDAO.LoadByID<Employee>((long)emp.EmployeeOid);
var urlaubskontos = BerechneUrlaubskonto(ent, year);
var aktuellesKonto = urlaubskontos.First(u => u.Key == year);
// Verfallsdatum der Urlaubstage des letzten Jahres
var expDate = GetExpirationDate(year).ToString().Split(' ');
// Resturlaub und den verbleibenden Resturlaub nach Verfall erstellen
if (aktuellesKonto.Value.ResturlaubVorjahrTotal != 0)
{
//dcs.Add(new UrlaubskontoDarstellungDC()
//{
// Erlaeuterung = "Resturlaub aus " + (year - 1),
// AnzahlTage = string.Format("+{0:0.00}", aktuellesKonto.Value.ResturlaubVorjahrTotal),
// Herkunft = string.Format("EmpOid:{0} Urlaubskonto:{1}", emp.EmployeeOid, year),
// Tooltip = null,
// IsDeletable = false,
// DatumZurSortierung = null
//});
//dcs.Add(new UrlaubskontoDarstellungDC()
//{
// Erlaeuterung = string.Format("\tdavon am {0} verfallen: ", expDate[0]),
// AnzahlTage = aktuellesKonto.Value.VerfallenerUrlaub,
// Herkunft = string.Format("EmpOid:{0} Urlaubskonto:{1}", emp.EmployeeOid, year),
// Tooltip = null,
// IsDeletable = false
//});
dcs.Add(new UrlaubskontoDarstellungDC()
{
//Erlaeuterung = "\tübrig: ",
Erlaeuterung = "Resturlaub aus " + (year - 1) + " nach Verfall:",
AnzahlTage = string.Format("+{0:0.00}", aktuellesKonto.Value.ResturlaubVorjahrTotal - aktuellesKonto.Value.VerfallenerUrlaub),
Herkunft = string.Format("EmpOid:{0} Urlaubskonto:{1}", emp.EmployeeOid, year),
Tooltip = null,
IsDeletable = false
}) ;
}
// Abzuziehende Tage wegen Vertragsbeginn mitten im Jahr
decimal tageNachAbzug = 0;
int arbeitstage = contract.WeeklyDays != null ? (int)contract.WeeklyDays : 0;
DateTime? endDate = contract.ContractEndDate == null ? new DateTime(year, 12, 31) : contract.ContractEndDate;
/*HIER NOCHMAL DRÜBER GUCKEN, VERMUTLICH FEHLER*/
if (contract.EntryDate.Value.Year == year || endDate.Value.Year == year) // Endet oder beginnt Vertrag in gewähltem Jahr
{
if (contract.EntryDate.Value.Year == year)
{
if (endDate >= new DateTime(contract.EntryDate.Value.Year, 12, 31)) // Wenn Vertrag länger gilt als das gewählte Jahr
{
int restlicheTageImJahr = Convert.ToInt32((new DateTime(contract.EntryDate.Value.Year, 12, 31) - contract.EntryDate.Value.Date).TotalDays);
tageNachAbzug = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, null, arbeitstage, restlicheTageImJahr, aktuellesKonto.Value.Urlaubsanspruch);
}
else // Wenn Ende des Vertrags im gleichen Jahr vor Jahresende ist
{
int restlicheTageImJahr = Convert.ToInt32((contract.ContractEndDate.Value.Date - contract.EntryDate.Value.Date).TotalDays);
tageNachAbzug = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, contract.ContractEndDate.Value.Date, arbeitstage, restlicheTageImJahr, aktuellesKonto.Value.Urlaubsanspruch);
}
}
if (endDate.Value.Year == year)
{
int restlicheTageImJahr = Convert.ToInt32(((DateTime)endDate - new DateTime(year, 1, 1)).TotalDays);
tageNachAbzug = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, endDate, arbeitstage, restlicheTageImJahr, aktuellesKonto.Value.Urlaubsanspruch);
}
var abzuziehendeTage = aktuellesKonto.Value.Urlaubsanspruch - tageNachAbzug;
if (abzuziehendeTage != 0)
{
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = "Wegen Vertragsbeginn/-ende abzuziehende Tage: ",
AnzahlTage = string.Format("-{0:0.00}", abzuziehendeTage),
Herkunft = string.Format("EmpOid:{0}", emp.EmployeeOid),
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = null
});
}
}
// Urlaube im Jahr
List<AbsenceTimeDC> urlaubstage = new List<AbsenceTimeDC>();
foreach (var abs in absences)
{
if (abs.Reason.Description.ToLower().Contains("urlaub"))
{
urlaubstage.Add(abs);
}
}
if(urlaubstage.Count > 0)
{
// Gesamtzahl an genommenen Urlaubstagen
decimal summeAllerUrlaube = 0;
//dcs.Add(new UrlaubskontoDarstellungDC()
//{
// Erlaeuterung = "Urlaubstage genommen:",
// AnzahlTage = summeAllerUrlaube,
// Herkunft = "UrlaubskontoEmployeeOid:" + emp.EmployeeOid,
// Tooltip = "ABCDEFG",
// IsDeletable = false
//});
// Urlaube durchgehen und die Tage zählen
foreach (var spanne in urlaubstage)
{
decimal summeTage = 0;
if (spanne.End == null) // Kein Ende
spanne.End = new DateTime(year, 12, 31);
else if (spanne.Start == spanne.End) // Nur ein Tag
summeTage++;
// Mehrere Tage
else
{
DateTime startForLoop = (spanne.Start.Value.Year == year) ? spanne.Start.Value : new DateTime(year, 1, 1);
while (startForLoop <= spanne.End.Value)
{
if (startForLoop.DayOfWeek != DayOfWeek.Saturday && startForLoop.DayOfWeek != DayOfWeek.Sunday)
{
summeTage++;
}
startForLoop = startForLoop.AddDays(1);
}
}
if (summeTage != 0)
{
var arbeitsfreieTage = GetFeiertage(year);
foreach (var tag in arbeitsfreieTage)
{
if (spanne.AbsenceSpan.ContainsDate(tag))
summeTage--;
}
}
// Urlaubs als Eintrag hinzufügen
var startAsArray = spanne.Start.Value.ToString().Split(' ');
var endAsArray = spanne.End.Value.ToString().Split(' ');
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = string.Format("Urlaub genommen von {0} bis {1}", startAsArray[0], endAsArray[0]),
AnzahlTage = string.Format("-{0:0.00}", summeTage),
Herkunft = string.Format("AbsenceOid: {0}", spanne.AbsenceTimeOid),
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = spanne.Start.Value
});
summeAllerUrlaube += summeTage;
}
// Eintrag finden, in dem die errechnete Summe aller Urlaubstage eingesetzt werden soll*
int index = 0;
for (int i = 0; i < dcs.Count; i++)
{
if (dcs[i].Tooltip == "ABCDEFG")
{
dcs[i].AnzahlTage = string.Format("-{0:0.00}", summeAllerUrlaube);
dcs[i].Tooltip = null;
break;
}
}
}
// Anzahl der daraus resultierenden Resturlaubstage
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = "Summe der verbleibenden Urlaubstage: ",
AnzahlTage = string.Format("={0:0.00}", aktuellesKonto.Value.Resturlaub),
Herkunft = "UrlaubskontoEmpOid" + aktuellesKonto.Value.EmployeeOid,
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = new DateTime(2999, 12, 31)
});
var sortierteDCs = dcs.OrderBy(dc => dc.DatumZurSortierung).ToList();
return sortierteDCs;
}
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);
var empService = new ServiceImplementations.EmployeeServiceImp();
var geschenkteUrlaubstage = empService.GetGeschenkteUrlaubstageForEmployee((long)emp.Oid);
// 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++)
{
if (konten.ContainsKey(i))
{
var tmp = konten[i];
decimal anzGeschenkteTage = 0.0m;
if (geschenkteUrlaubstage != null)
{
foreach (var item in geschenkteUrlaubstage)
{
if (item.Date.Year == i)
anzGeschenkteTage += item.AnzahlTage;
}
}
if (contract.EmploymentType.LeaveDays != null)
contract.LeaveDays = contract.EmploymentType.LeaveDays;
tmp.Urlaubsanspruch += contract.LeaveDays + anzGeschenkteTage ?? 0;
tmp.Resturlaub = tmp.Urlaubsanspruch;
int arbeitstage = contract.WeeklyDays != null ? (int)contract.WeeklyDays : 0;
DateTime? endDate = contract.ContractEndDate == null ? new DateTime(year, 12, 31) : contract.ContractEndDate;
if (contract.EntryDate.Value.Year == i)
{
if (endDate >= new DateTime(contract.EntryDate.Value.Year, 12, 31))
{
int restlicheTageImJahr = Convert.ToInt32((new DateTime(contract.EntryDate.Value.Year, 12, 31) - contract.EntryDate.Value.Date).TotalDays);
tmp.Resturlaub = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, null, arbeitstage, restlicheTageImJahr, tmp.Urlaubsanspruch);
}
else // Wenn Ende des Vertrags im gleichen Jahr vor Ende des Jahres ist
{
int restlicheTageImJahr = Convert.ToInt32((contract.ContractEndDate.Value.Date - contract.EntryDate.Value.Date).TotalDays);
tmp.Resturlaub = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, contract.ContractEndDate.Value.Date, arbeitstage, restlicheTageImJahr, tmp.Urlaubsanspruch);
}
}
if (endDate.Value.Year == i)
{
int restlicheTageImJahr = Convert.ToInt32(((DateTime)endDate - new DateTime(i, 1, 1)).TotalDays);
tmp.Resturlaub = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, endDate, arbeitstage, restlicheTageImJahr, 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 start = (absence.Start.Value.Year == year) ? absence.Start.Value : new DateTime(year, 1, 1);
var end = DateTimeExtensions.GetMin(absence.End, new DateTime(absYear, 12, 31));
var dauer = BerechneAnzahlUrlaubstage(emp, absence, year);
var expiration = GetExpirationDate(year);
current.UrlaubsVerfallsdatum = expiration;
// 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;
}
else if (start > expiration)
{
current.VerfallenerUrlaub = current.ResturlaubVorjahr;
}
// Restliche Dauer vom Urlaub abziehen
current.Resturlaub -= dauer;
}
return konten;
}
catch (Exception e)
{
throw e;
}
}
private decimal CalcCorrectNumberOfLeaveDaysForSpecialContractSituation(DateTime entryDate, DateTime? endDate, int anzahlArbeitstage, int restlicheTageImJahr, decimal? urlaubstageProJahr)
{
decimal urlaubstage = 0;
if (urlaubstageProJahr == null)
urlaubstageProJahr = 0m;
if (entryDate.Day == 1 && entryDate.Month == 1 || entryDate.Day == 2 && entryDate.Month == 1) //Erster Tag im Jahr
{
//Prüfen, ob Enddatum Ende des Jahres oder früher ist
if (endDate == null)
{
if (anzahlArbeitstage < 5) // weniger als 5 Tage
urlaubstage = (decimal)urlaubstageProJahr / 5m * anzahlArbeitstage;
else
{
if (anzahlArbeitstage == 5) // 5 Tage
urlaubstage = (decimal)urlaubstageProJahr;
else if (anzahlArbeitstage == 6) // 6 Tage
urlaubstage = (decimal)urlaubstageProJahr;
}
}
else
{
if (anzahlArbeitstage < 5) // weniger als 5 Tage
urlaubstage = (decimal)urlaubstageProJahr / 5m * anzahlArbeitstage;
else
{
if (anzahlArbeitstage == 5) // 5 Tage
urlaubstage = (decimal)urlaubstageProJahr / 365m * restlicheTageImJahr;
else if (anzahlArbeitstage == 6) // 6 Tage
urlaubstage = (decimal)urlaubstageProJahr / 365m * restlicheTageImJahr;
}
}
}
else if (/*entryDate.Day > 1 && */anzahlArbeitstage < 5) // Mitten im Jahr, weniger als 5 Tage
{
urlaubstage = (decimal)urlaubstageProJahr / 5m * 3m / 365m * restlicheTageImJahr;
}
else if (/*entryDate.Day > 1 && */anzahlArbeitstage >= 5) // Mitten im Jahr, 5 oder 6 Tage
{
urlaubstage = (decimal)urlaubstageProJahr / 365m * restlicheTageImJahr;
}
// Runden
if (urlaubstage - (int)urlaubstage <= 0.1m)
{
urlaubstage = Math.Round(urlaubstage, MidpointRounding.AwayFromZero);
}
else if (urlaubstage - (int)urlaubstage <= 0.5m)
{
decimal digits = urlaubstage - (int)urlaubstage;
urlaubstage = urlaubstage - digits + 0.5m;
}
else if (urlaubstage - (int)urlaubstage <= 1.0m)
{
urlaubstage = Math.Ceiling(urlaubstage);
}
return urlaubstage;
}
private decimal BerechneAnzahlUrlaubstage(Employee emp, AbsenceTime absence, int year)
{
if (absence.Start.HasValue)
{
int days = 0;
//DateTime start = absence.Start.Value;
DateTime start = (absence.Start.Value.Year == year) ? absence.Start.Value : new DateTime(year, 1, 1);
DateTime end = start;
DateTime maxend = new DateTime(year, 12, 31);
if (absence.End.HasValue)
{
end = absence.End.Value;
}
if (maxend < end)
{
end = maxend;
}
while (start <= end)
{
if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday && !IstFeiertag(start))
{
days++;
}
start = start.AddDays(1);
}
return (decimal)days;
}
return 0;
}
private decimal BerechneAnzahlUrlaubstage2(AbsenceTimeDC absence, int year)
{
if (absence.Start.HasValue)
{
int days = 0;
DateTime start = absence.Start.Value;
DateTime end = start;
DateTime maxend = new DateTime(year, 12, 31);
if (absence.End.HasValue)
{
end = absence.End.Value;
}
if (maxend < end)
{
end = maxend;
}
while (start <= end)
{
if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday && !IstFeiertag(start))
{
days++;
}
start = start.AddDays(1);
}
return (decimal)days;
}
return 0;
}
}
}