Files
BeWoPlaner/Service/Plugins/VacationService.cs

875 lines
47 KiB
C#
Raw Normal View History

2017-06-11 16:01:01 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
2017-06-11 16:01:01 +02:00
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceImplementations;
2017-06-11 16:01:01 +02:00
using BS.Shared;
using BS.Shared.Core;
2018-10-08 11:57:16 +02:00
using BS.Shared.DataContracts;
2017-06-11 16:01:01 +02:00
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
namespace BeWo.Service.Plugins
{
public class VacationService : AbstractIDSpecificDefaultClass<VacationService>
{
private List<DateTime> _Feiertage { get;set; }
2017-06-11 16:01:01 +02:00
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)
{
2018-10-08 11:57:16 +02:00
var list = GetFeiertage(year, "NRW");
2018-10-08 11:57:16 +02:00
return list.Select(f => f.Datum).ToList();
}
public FeiertagDC GetFeiertag(DateTime start)
{
var feiertage = GetFeiertage(start.Year, "NRW");
2018-10-08 11:57:16 +02:00
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" });
2017-06-11 16:01:01 +02:00
//list.Add(new DateTime(year, 1, 6)); // , "Heilige Drei Könige"));
2018-10-08 11:57:16 +02:00
list.Add(new FeiertagDC { Datum = new DateTime(year, 5, 1), Name = "Tag der Arbeit" });
2017-06-11 16:01:01 +02:00
//list.Add(new DateTime(year, 8, 15)); // , "Mariä Himmelfahrt"));
2018-10-08 11:57:16 +02:00
list.Add(new FeiertagDC { Datum = new DateTime(year, 10, 3), Name = "Tag der dt. Einheit" });
2017-06-11 16:01:01 +02:00
//list.Add(new DateTime(year, 10, 31)); // , "Reformationstag"));
2018-10-08 11:57:16 +02:00
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" });
2017-06-11 16:01:01 +02:00
if (year == 2017)
{
2018-10-08 11:57:16 +02:00
list.Add(new FeiertagDC { Datum = new DateTime(year, 10, 31), Name = "Reformationstag" });
2017-06-11 16:01:01 +02:00
}
DateTime osterSonntag = GetOsterSonntag(year);
//list.Add(osterSonntag); // , "Ostersonntag"));
//list.Add(osterSonntag.AddDays(-3)); // , "Gründonnerstag")); q
//list.Add(osterSonntag.AddDays(-48)); // , "Rosenmontag"));
2018-10-08 11:57:16 +02:00
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" });
2017-06-11 16:01:01 +02:00
2018-10-08 11:57:16 +02:00
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(50), Name = "Pfingstmontag" });
list.Add(new FeiertagDC { Datum = osterSonntag.AddDays(60), Name = "Fronleichnam" });
2017-06-11 16:01:01 +02:00
return list;
}
public static DateTime GetOsterSonntag(int year)
{
int g, h, c, j, l, i;
2018-10-08 11:57:16 +02:00
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;
2017-06-11 16:01:01 +02:00
l = i - j;
int month = (int)(3 + ((l + 40) / 44));
int day = (int)(l + 28 - 31 * (month / 4));
2017-06-11 16:01:01 +02:00
return new DateTime(year, month, day);
}
2018-10-08 11:57:16 +02:00
public virtual List<FerienDC> GetFerien(String bundesland = "nrw")
{
List<FerienDC> list = new List<FerienDC>();
2021-01-12 01:12:03 +01:00
if (bundesland.ToLower() == "nrw")
{
2021-01-12 01:12:03 +01:00
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) });
}
2021-06-20 23:11:01 +02:00
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) });
2021-11-30 17:06:41 +01:00
list.Add(new FerienDC() { Name = "Winterferien 2022", Start = new DateTime(2022, 1, 31), Ende = new DateTime(2022, 2, 1) });
list.Add(new FerienDC() { Name = "Osterferien 2022", Start = new DateTime(2022, 4, 4), Ende = new DateTime(2022, 4, 19) });
list.Add(new FerienDC() { Name = "Pfingstferien 2022", Start = new DateTime(2022, 5, 27), Ende = new DateTime(2022, 5, 27) }); //Brückentag Himmelfahrt
list.Add(new FerienDC() { Name = "Pfingstferien 2022", Start = new DateTime(2022, 6, 7), Ende = new DateTime(2022, 6, 7) }); //Pfingstdienstag
list.Add(new FerienDC() { Name = "Sommerferien 2022", Start = new DateTime(2022, 7, 14), Ende = new DateTime(2022, 8, 24) });
list.Add(new FerienDC() { Name = "Herbstferien 2022", Start = new DateTime(2022, 10, 17), Ende = new DateTime(2022, 10, 28) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2022", Start = new DateTime(2022, 12, 23), Ende = new DateTime(2023, 1, 6) });
list.Add(new FerienDC() { Name = "Winterferien 2023", Start = new DateTime(2023, 1, 30), Ende = new DateTime(2023, 1, 31) });
list.Add(new FerienDC() { Name = "Osterferien 2023", Start = new DateTime(2023, 3, 27), Ende = new DateTime(2023, 4, 11) });
list.Add(new FerienDC() { Name = "Pfingstferien 2023", Start = new DateTime(2023, 5, 19), Ende = new DateTime(2023, 5, 19) }); //Brückentag Himmelfahrt
list.Add(new FerienDC() { Name = "Pfingstferien 2023", Start = new DateTime(2023, 5, 30), Ende = new DateTime(2023, 5, 30) }); //Pfingstdienstag
list.Add(new FerienDC() { Name = "Sommerferien 2023", Start = new DateTime(2023, 7, 6), Ende = new DateTime(2023, 8, 16) });
list.Add(new FerienDC() { Name = "Brückentag 2023", Start = new DateTime(2023, 10, 2), Ende = new DateTime(2023, 10, 2) });
list.Add(new FerienDC() { Name = "Herbstferien 2023", Start = new DateTime(2023, 10, 16), Ende = new DateTime(2023, 10, 30) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2023", Start = new DateTime(2023, 12, 27), Ende = new DateTime(2024, 1, 5) });
2021-06-20 23:11:01 +02:00
}
2021-12-09 14:25:27 +01:00
else if (bundesland.ToLower() == "hessen")
{
2022-01-17 16:38:00 +01:00
list.Add(new FerienDC() { Name = "Osterferien 2021", Start = new DateTime(2021, 4, 6), Ende = new DateTime(2021, 4, 16) });
list.Add(new FerienDC() { Name = "Sommerferien 2021", Start = new DateTime(2021, 7, 19), Ende = new DateTime(2021, 8, 27) });
list.Add(new FerienDC() { Name = "Herbstferien 2021", Start = new DateTime(2021, 10, 11), Ende = new DateTime(2021, 10, 23) });
2021-12-09 14:25:27 +01:00
list.Add(new FerienDC() { Name = "Weihnachtsferien 2021", Start = new DateTime(2021, 12, 23), 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, 7, 25), Ende = new DateTime(2022, 9, 2) });
list.Add(new FerienDC() { Name = "Herbstferien 2022", Start = new DateTime(2022, 10, 24), Ende = new DateTime(2022, 10, 29) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2022", Start = new DateTime(2022, 12, 22), Ende = new DateTime(2023, 1, 7) });
list.Add(new FerienDC() { Name = "Osterferien 2023", Start = new DateTime(2023, 4, 3), Ende = new DateTime(2023, 4, 22) });
list.Add(new FerienDC() { Name = "Sommerferien 2023", Start = new DateTime(2023, 7, 24), Ende = new DateTime(2023, 9, 1) });
list.Add(new FerienDC() { Name = "Herbstferien 2023", Start = new DateTime(2023, 10, 23), Ende = new DateTime(2023, 10, 28) });
list.Add(new FerienDC() { Name = "Weihnachtsferien 2023", Start = new DateTime(2023, 12, 27), Ende = new DateTime(2024, 1, 13) });
}
2018-10-08 11:57:16 +02:00
return list;
}
2020-09-30 10:00:31 +02:00
private void SetLokaleFeiertagListe(int year)
{
_Feiertage = GetFeiertage(year);
}
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();
// Urlaubskonto erstellen
var ent = DAOFactory.GenericDAO.LoadByID<Employee>((long)emp.EmployeeOid);
var urlaubskonten = BerechneUrlaubskonto(ent, year);
var aktuellesKonto = urlaubskonten.First(u => u.Key == year);
var geschenkteUrlaubstage = es.GetGeschenkteUrlaubstageForEmployee((long)emp.EmployeeOid);
// Benötigt werden:
// 1. Vetragliche Urlaubstage für´s Jahr
List<ContractDC> contracts = new List<ContractDC>();
// Vertrag für Jahr raussuchen
foreach (var c in emp.Contracts)
{
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) // Wenn das ausgewählte Jahr zwischen Vertragsbeginn und -ende liegt
contracts.Add(c);
}
if (contracts.Count == 0) // Kein Vertrag = kein Urlaubskonto
return null;
// 2. Abzuziehende Tage wegen Vertragsbeginn mitten im Jahr
foreach (var contract in contracts)
{
2021-09-15 11:00:00 +02:00
#region Vielleicht bald unnötig
// Zahlen für Darstellung in View
decimal tageNachAbzug = 0;
decimal abzuziehendeTage = 0;
2021-10-18 00:43:47 +02:00
int arbeitstage = contract.WeeklyDays; // Vertragliche Arbeitstage
DateTime? endDate = contract.ContractEndDate == null ? new DateTime(year, 12, 31) : contract.ContractEndDate; // Ende des Vertrags auf letzten Tag des Jahres setzen, wenn kein Ende
2021-10-18 00:43:47 +02:00
var leaveDays = contract.EmploymentType?.LeaveDays == null ? contract.LeaveDays : contract.EmploymentType.LeaveDays; // Vertragliche Urlaubstage
if (!leaveDays.HasValue)
{
leaveDays = 0;
}
if (contract.EntryDate.HasValue && (contract.EntryDate.Value.Year == year || endDate.Value.Year == year)) // Wenn Vertrag im gewählten Jahr beginnt oder endet
{
if (contract.EntryDate.Value.Year == year) // Wenn Vertrag im gewählten Jahr beginnt
{
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, leaveDays);
}
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, leaveDays);
}
}
else if (endDate.Value.Year == year) // Wenn Vertrag im gewählten Jahr endet
{
int restlicheTageImJahr = Convert.ToInt32(((DateTime)endDate - new DateTime(year, 1, 1)).TotalDays);
tageNachAbzug = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, endDate, arbeitstage, restlicheTageImJahr, leaveDays);
}
// Abzuziehende Tage = Vertragliche Urlaubstage - Tage, die nach Abzug der verfallenden Tage übrig bleiben
abzuziehendeTage = (decimal)leaveDays - tageNachAbzug;
}
2021-09-15 11:00:00 +02:00
#endregion
var contractStart = contract.EntryDate.Value.ToString().Split(' ');
var contractEnd = contract.ContractEndDate != null ? contract.ContractEndDate.Value.ToString().Split(' ') : null;
2021-10-18 00:43:47 +02:00
var anzahlTage = leaveDays - abzuziehendeTage;
var obereZeile = new UrlaubskontoDarstellungDC()
{
2021-10-18 00:43:47 +02:00
AnzahlTage = string.Format("{0:0.00}", anzahlTage),
Herkunft = string.Format("EmpOid:{0} ContractOid:{1}", emp.EmployeeOid, contract.ContractOid),
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = null
};
obereZeile.Erlaeuterung = contractEnd == null ? "Urlaubstage laut Vertrag vom " + contractStart[0] + ":" : "Urlaubstage laut Vertrag vom " + contractStart[0] + " bis " + contractEnd[0] + ":";
dcs.Add(obereZeile);
#region Würde Code von 2. sparen, klappt aber leider nur dann, wenn es nicht mehr als einen Vertrag im Jahr gibt
//decimal anzGeschenkteTage = 0.0m;
//if (geschenkteUrlaubstage != null)
//{
// foreach (var item in geschenkteUrlaubstage)
// {
// if (item.Date.Year == year)
// anzGeschenkteTage += item.AnzahlTage;
// }
//}
//var testvar = aktuellesKonto.Value.Urlaubsanspruch - anzGeschenkteTage;
//var obereZeile = new UrlaubskontoDarstellungDC()
//{
// AnzahlTage = testvar,
// Herkunft = string.Format("EmpOid:{0} ContractOid:{1}", emp.EmployeeOid, contract.ContractOid),
// Tooltip = null,
// IsDeletable = false,
// DatumZurSortierung = null
//};
//obereZeile.Erlaeuterung = contractEnd == null ? "Urlaubstage laut Vertrag vom " + contractStart[0] + ":" : "Urlaubstage laut Vertrag vom " + contractStart[0] + " bis " + contractEnd[0] + ":";
//dcs.Add(obereZeile);
#endregion
}
// 3. Geschenkte Urlaubstage im Jahr
if (geschenkteUrlaubstage.Count > 0 && geschenkteUrlaubstage.Any(g => g.Date.Year == year))
{
// 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
});
}
}
}
// 4. Verfallener Resturlaub
// Verfallsdatum der Urlaubstage des letzten Jahres zur Darstellung (also ohne Uhrzeit)
var expDate = GetExpirationDate(year).ToString().Split(' ');
// Resturlaub und den verbleibenden Resturlaub nach Verfall erstellen
if (aktuellesKonto.Value.ResturlaubVorjahrTotal != 0) // Wenn Urlaub aus dem Vorjahr mitgenommen wurde
{
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
}) ;
}
if (aktuellesKonto.Value.VerfallenerUrlaub != 0) // Wenn Urlaubstage verfallen sind
{
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = string.Format("Urlaub am {0} verfallen: ", expDate[0]),
AnzahlTage = string.Format("-{0:0.00}", aktuellesKonto.Value.VerfallenerUrlaub),
DatumZurSortierung = GetExpirationDate(year),
Tooltip = null,
IsDeletable = false
});
}
// 5. 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).ToList();
if (absences.Count > 0) // Wenn es Urlaube in dem Jahr gibt
{
// Urlaube durchgehen und die Tage zählen
foreach (var spanne in absences)
{
decimal summeTage = 0;
#region Urlaubstage zählen
if (spanne.End == null) // Wenn es kein Ende gibt, Ende auf letzten Tag im Jahr setzen
spanne.End = new DateTime(year, 12, 31);
2021-09-22 15:34:38 +02:00
if (spanne.Start.Value.Date == spanne.End.Value.Date && spanne.Start.Value.TimeOfDay == spanne.End.Value.TimeOfDay) // ein ganzer Tag Urlaub
summeTage++;
2021-09-22 15:34:38 +02:00
else if (spanne.Start.Value.Date == spanne.End.Value.Date && spanne.Start.Value.TimeOfDay != spanne.End.Value.TimeOfDay)
summeTage += 0.5m;
else // Mehr als ein Tag Urlaub
{
DateTime startForLoop = (spanne.Start.Value.Year == year) ? spanne.Start.Value : new DateTime(year, 1, 1);
// Tage auf den Zähler addieren, solange das sich erhöhende Datum vor dem Enddatum ist und wenn das Datum kein Wochenend- oder Feiertag ist
2021-09-22 15:34:38 +02:00
while (startForLoop <= spanne.End.Value)
{
if (startForLoop.DayOfWeek != DayOfWeek.Saturday && startForLoop.DayOfWeek != DayOfWeek.Sunday && !_Feiertage.Contains(startForLoop))
summeTage++;
startForLoop = startForLoop.AddDays(1);
}
}
#endregion
// Start- und Enddatum des Urlaubs für Darstellung vorbereiten
var startAsArray = spanne.Start.Value.ToString().Split(' ');
var endAsArray = spanne.End.Value.ToString().Split(' ');
// Eintrag für Urlaubstag setzen (Erläuterung abhängig davon, ob Urlaub nur ein Tag geht oder über mehrere
dcs.Add(new UrlaubskontoDarstellungDC()
{
Erlaeuterung = startAsArray[0] == endAsArray[0] ? string.Format("Urlaub genommen am {0}", startAsArray[0]) :
string.Format("Urlaub genommen vom {0} bis {1}", startAsArray[0], endAsArray[0]),
AnzahlTage = string.Format("-{0:0.00}", summeTage),
Herkunft = string.Format("AbsenceOid: {0}", spanne.AbsenceTimeOid),
Tooltip = spanne.Notice,
IsDeletable = false,
DatumZurSortierung = spanne.Start.Value
});
}
}
// 6. Anzahl der aus 1.-5. resultierenden Resturlaubstage fürs Jahr, also Resturlaub vom Urlaubskonto
dcs.Add(new UrlaubskontoDarstellungDC()
{
AnzahlTage = string.Format("={0:0.00}", aktuellesKonto.Value.Resturlaub),
Erlaeuterung = "Summe der verbleibenden Urlaubstage: ",
Herkunft = "UrlaubskontoEmpOid" + aktuellesKonto.Value.EmployeeOid,
Tooltip = null,
IsDeletable = false,
DatumZurSortierung = new DateTime(2999, 12, 31)
});
//Liste der DCs nach Datum sortieren, um eine zeitliche Hierarchie zu schaffen
var sortierteDCs = dcs.OrderBy(dc => dc.DatumZurSortierung).ToList();
return sortierteDCs;
}
public virtual Dictionary<int, UrlaubskontoDC> BerechneUrlaubskonto(Employee emp, int year)
{
try
{
SetLokaleFeiertagListe(year);
2021-09-15 11:00:00 +02:00
// Alle Abwesenheiten bis zu dem Jahr raussuchen, für das man das Urlaubskonto berechnen will
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);
2021-09-15 11:00:00 +02:00
var empService = new EmployeeServiceImp();
// Startzeitpunkt für Berechnung berechnen
2021-09-15 11:00:00 +02:00
var firstContractYear = emp.Contracts?.Min(x => x.EntryDate)?.Year ?? int.MaxValue; // Den Vetrag raussuchen, der am frühesten beginnt
var firstAbsenceTimeYear = absences.Min(x => x.Start)?.Year ?? int.MaxValue; // Jahr der ersten Abwesenheit
var firstYear = Math.Min(year, Math.Min(firstContractYear, firstAbsenceTimeYear)); // Erstes, für´s Urlaubskonto relevante Jahr
2017-06-11 16:01:01 +02:00
2021-09-15 11:00:00 +02:00
// Urlaubskonten erzeugen, eins für jedes Jahr ab dem ersten bis zum ausgewählten Jahr
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;
2021-09-15 11:00:00 +02:00
// Durch jedes Jahr des Vertrags gehen
for (int i = start; i <= end; i++)
{
2021-01-12 01:12:03 +01:00
if (konten.ContainsKey(i))
{
2021-09-15 11:00:00 +02:00
// Konto für aktuelles Jahr in Schleife auswählen
2021-01-12 01:12:03 +01:00
var tmp = konten[i];
2021-10-18 00:43:47 +02:00
if (contract.EmploymentType?.LeaveDays != null)
contract.LeaveDays = contract.EmploymentType.LeaveDays;
2021-10-18 00:43:47 +02:00
2021-09-15 11:00:00 +02:00
//Hier wird nun der Urlaubsanspruch für ein Jahr errechnet, in dem der Vertrag beginnt oder aufhört. (Siehe CalcCorrectNumberOfLeaveDaysForSpecialContractSituation())
var urlaubsanspruchFuerVertragInLoop = contract.LeaveDays ?? 0;
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 || endDate.Value.Year == i) // Endet oder beginnt Vertrag in gewähltem Jahr
{
decimal errechneteTage = 0;
decimal weggefallen = 0;
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);
errechneteTage = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, null, arbeitstage, restlicheTageImJahr, urlaubsanspruchFuerVertragInLoop);
}
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);
errechneteTage += CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, contract.ContractEndDate.Value.Date, arbeitstage, restlicheTageImJahr, urlaubsanspruchFuerVertragInLoop);
}
}
else if (endDate.Value.Year == i)
{
int restlicheTageImJahr = Convert.ToInt32(((DateTime)endDate - new DateTime(i, 1, 1)).TotalDays);
errechneteTage += CalcCorrectNumberOfLeaveDaysForSpecialContractSituation((DateTime)contract.EntryDate, endDate, arbeitstage, restlicheTageImJahr, urlaubsanspruchFuerVertragInLoop);
}
2021-09-15 11:00:00 +02:00
// Resturlaub und Urlaubsanspruch auf errechnete Werte setzen
weggefallen = urlaubsanspruchFuerVertragInLoop - errechneteTage;
tmp.Resturlaub += errechneteTage;
tmp.Urlaubsanspruch += urlaubsanspruchFuerVertragInLoop - weggefallen;
}
else
{
tmp.Urlaubsanspruch += urlaubsanspruchFuerVertragInLoop;
tmp.Resturlaub = tmp.Urlaubsanspruch;
}
2021-01-12 01:12:03 +01:00
}
}
}
2021-09-15 11:00:00 +02:00
// Abwesenheiten in Jahr x zu einem Dictionary hinzufügen
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();
Dictionary<int, decimal> zuVerfallZuAddieren = new Dictionary<int, decimal>();
2021-09-15 11:00:00 +02:00
// Alle Abwesenheiten durchlaufen, deren Dauer berechnen und vom Resturlaub abziehen, sofern es nicht nutzbaren Resturlaub vom Vorjahr gibt
foreach (var tuple in absencesYear)
{
var absYear = tuple.Item1;
var absence = tuple.Item2;
2021-09-15 11:00:00 +02:00
// Resturlaub aus 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];
2021-09-15 11:00:00 +02:00
// Start und Ende auf Jahresanfang/-ende setzen, wenn Start des Urlaubs im Vorjahr oder Ende des Urlaubs im nächsten Jahr liegt
var start = DateTimeExtensions.GetMax(absence.Start, new DateTime(absYear, 1, 1));
var end = DateTimeExtensions.GetMin(absence.End, new DateTime(absYear, 12, 31));
2021-01-12 01:12:03 +01:00
2021-09-15 11:00:00 +02:00
// Dauer des Urlaubs unter Berücksichtigung von Wochenend- und Feiertagen berechnen
var dauer = BerechneAnzahlUrlaubstage(absence, null, absYear);
2021-09-15 11:00:00 +02:00
// Verfallsdatum des Urlaubs festlegen
var expiration = GetExpirationDate(absYear);
current.UrlaubsVerfallsdatum = expiration;
2021-09-15 11:00:00 +02:00
// Resturlaub vom Vorjahr verwenden, wenn Resturlaub aus dem Vorjahr existiert und der Urlaub vor dem Verfallsdatum beginnt
if (current.ResturlaubVorjahr > 0 && start <= expiration)
{
var firstEnd = (DateTime)DateTimeExtensions.GetMin(end, expiration); // Ende von Urlaub oder Verfallsdatum, je nachdem was früher ist
2021-09-15 11:00:00 +02:00
var dauerVorjahr = 0;
DateTime zaehlerDatum = (DateTime)start;
2021-09-15 11:00:00 +02:00
// Urlaubstagzähler erhöhen, wenn aktueller Tag der Schleife weder ein Wochenend- noch ein Feiertag ist
while (zaehlerDatum <= firstEnd)
{
if (zaehlerDatum.DayOfWeek != DayOfWeek.Saturday && zaehlerDatum.DayOfWeek != DayOfWeek.Sunday && !_Feiertage.Contains(zaehlerDatum))
dauerVorjahr++;
zaehlerDatum = zaehlerDatum.AddDays(1);
}
var bucheVorjahr = Math.Min(current.ResturlaubVorjahr, dauerVorjahr);
current.ResturlaubVorjahr -= bucheVorjahr;
dauer -= bucheVorjahr;
if (dauer < 0)
{
if (!zuVerfallZuAddieren.ContainsKey(absYear))
zuVerfallZuAddieren.Add(absYear, 0);
zuVerfallZuAddieren[absYear] -= dauer;
}
}
2021-09-15 11:00:00 +02:00
else if (start > expiration) // Wenn der Urlaub nach dem Verfallsdatum beginnt, ist der verfallene Urlaub gleich dem Urlaub, der aus dem Vorjahr übrig ist
{
current.VerfallenerUrlaub = zuVerfallZuAddieren.ContainsKey(absYear) ? current.ResturlaubVorjahr + zuVerfallZuAddieren[absYear] : current.ResturlaubVorjahr;
}
// Restliche Dauer vom Urlaub abziehen
current.Resturlaub -= dauer < 0 ? 0 : dauer; // ausprobieren
}
// Als letztes geschenkte Urlaubstage draufrechnen
var geschenkteUrlaubstage = empService.GetGeschenkteUrlaubstageForEmployee((long)emp.Oid);
foreach (var konto in konten)
{
var i = konto.Key;
2021-09-15 11:00:00 +02:00
2021-09-15 11:00:00 +02:00
// Wenn es geschenkte Tage gibt, Liste durchlaufen und für jeden Eintrag den Zähler entsprechend der Tage erhöhen
if (geschenkteUrlaubstage != null)
{
2021-09-15 11:00:00 +02:00
// Zähler für die Anzahl der geschenkten Tage für das ganze Jahr (i)
decimal anzGeschenkteTage = 0.0m;
foreach (var item in geschenkteUrlaubstage)
{
if (item.Date.Year == i)
anzGeschenkteTage += item.AnzahlTage;
}
2021-09-15 11:00:00 +02:00
// Geschenkte Tage auf Anspruch und Resturlaub addieren
konto.Value.Urlaubsanspruch += anzGeschenkteTage;
konto.Value.Resturlaub += anzGeschenkteTage;
}
}
return konten;
}
catch (Exception e)
{
throw e;
}
}
2021-01-12 01:12:03 +01:00
// Methode zur Berechnung der Urlaubstage, wenn Vertrag mitten im Jahr beginnt oder endet.
// BSP: 30 Urlaubstage, Beginn am 01.06.; Dann entfallen eine bestimmte Anzahl an Tagen, das wird hier berechnet
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)
urlaubstage = (decimal)urlaubstageProJahr;
else if (endDate.Value.Day == 31 && endDate.Value.Month == 12)
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;
}
public decimal BerechneAnzahlUrlaubstage(AbsenceTime absence, AbsenceTimeDC absenceDC, int year)
2021-01-12 01:12:03 +01:00
{
if (absence != null)
2021-01-12 01:12:03 +01:00
{
if (absence.Start.HasValue)
{
decimal days = 0;
//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))
{
if (start.Date == end.Date && start.TimeOfDay != end.TimeOfDay)
days += 0.5m;
else
days++;
}
start = start.AddDays(1);
}
return (decimal)days;
}
}
else if (absenceDC != null)
{
if (absenceDC.Start.HasValue)
{
decimal days = 0;
//int days = 0;
//DateTime start = absence.Start.Value;
DateTime start = (absenceDC.Start.Value.Year == year) ? absenceDC.Start.Value : new DateTime(year, 1, 1);
DateTime end = start;
DateTime maxend = new DateTime(year, 12, 31);
if (absenceDC.End.HasValue)
{
end = absenceDC.End.Value;
}
if (maxend < end)
{
end = maxend;
}
while (start <= end)
{
if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday && !IstFeiertag(start))
{
if (start.Date == end.Date && start.TimeOfDay != end.TimeOfDay)
days += 0.5m;
else
days++;
}
start = start.AddDays(1);
}
return (decimal)days;
}
}
return 0;
}
public Dictionary<long?, decimal> BerechneAnzEinerAbwesenheitFuerMehrereMitarbeiter(List<long?> empOids, int year, string reason)
{
SetLokaleFeiertagListe(year);
EmployeeServiceImp es = new EmployeeServiceImp();
var absences = es.GetAllEmployeeAbsenceTimesForYear(year).Where(abs => abs.Reason.Description.ToLower().Contains(reason.ToLower()));
2021-01-12 01:12:03 +01:00
Dictionary<long?, decimal> urlaubGenommenProMitarbeiter = new Dictionary<long?, decimal>();
2021-01-12 01:12:03 +01:00
foreach (var oid in empOids)
{
var absencesForCurrentEmp = absences.Where(a => a.EmployeeOid == oid);
decimal tage = 0;
foreach (var abs in absencesForCurrentEmp)
2021-01-12 01:12:03 +01:00
{
var start = (DateTime)DateTimeExtensions.GetMax(abs.Start, new DateTime(year, 1, 1));
var end = (DateTime)DateTimeExtensions.GetMin(abs.End != null ? abs.End: new DateTime(year, 12, 31), new DateTime(year, 12, 31));
while (start <= end)
2021-01-12 01:12:03 +01:00
{
if (start.DayOfWeek != DayOfWeek.Saturday && start.DayOfWeek != DayOfWeek.Sunday && !_Feiertage.Contains(start))
2021-09-22 15:34:38 +02:00
{
if (start.Date == end.Date && start.TimeOfDay != end.TimeOfDay)
tage += 0.5m;
else
tage++;
}
2021-01-12 01:12:03 +01:00
start = start.AddDays(1);
}
2021-01-12 01:12:03 +01:00
}
urlaubGenommenProMitarbeiter.Add(oid, tage);
2021-01-12 01:12:03 +01:00
}
return urlaubGenommenProMitarbeiter;
2021-01-12 01:12:03 +01:00
}
}
}