2017-06-11 16:01:01 +02:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2020-10-13 14:35:06 +02:00
using System.Text.RegularExpressions ;
2017-06-11 16:01:01 +02:00
using BeWo.Data.Access ;
using BeWo.Data.Entities ;
using BeWo.Service.DCEntityMapper ;
2021-09-06 12:43:23 +02:00
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 >
{
2022-11-10 17:44:27 +01:00
private List < FeiertagDC > databaseFeiertage = null ;
2021-09-14 14:08:08 +02:00
private List < DateTime > _Feiertage { get ; set ; }
2022-08-30 08:53:24 +02:00
private string _Bundesland = "NRW" ;
2021-09-14 14:08:08 +02:00
2022-08-30 08:53:24 +02:00
public virtual string Bundesland
{
get
{
return _Bundesland ;
}
set
{
_Bundesland = value ;
}
}
2021-09-14 14:08:08 +02:00
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 )
{
2022-08-30 08:53:24 +02:00
var list = GetFeiertage ( year , Bundesland ) ;
2020-10-13 14:35:06 +02:00
2018-10-08 11:57:16 +02:00
return list . Select ( f = > f . Datum ) . ToList ( ) ;
}
2022-03-09 16:52:32 +01:00
public virtual FeiertagDC GetFeiertag ( DateTime start )
2018-10-08 11:57:16 +02:00
{
2022-08-30 08:53:24 +02:00
var feiertage = GetFeiertage ( start . Year , Bundesland ) ;
2020-10-13 14:35:06 +02:00
2018-10-08 11:57:16 +02:00
foreach ( var ft in feiertage )
{
if ( start = = ft . Datum )
return ft ;
}
return null ;
}
2022-03-09 16:52:32 +01:00
public virtual FerienDC GetFerien ( DateTime start , String bundesland )
2018-10-08 11:57:16 +02:00
{
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 )
{
2022-08-30 08:53:24 +02:00
2022-11-10 17:44:27 +01:00
2018-10-08 11:57:16 +02:00
List < FeiertagDC > list = new List < FeiertagDC > ( ) ;
2020-10-13 14:35:06 +02:00
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"));
2022-09-07 14:43:01 +02:00
list . Add ( new FeiertagDC { Datum = new DateTime ( year , 10 , 3 ) , Name = "Tag der Deutschen Einheit" } ) ;
2017-06-11 16:01:01 +02:00
//list.Add(new DateTime(year, 10, 31)); // , "Reformationstag"));
2023-01-05 13:56:27 +01:00
if ( bundesland . ToLower ( ) = = "bayern" )
{
list . Add ( new FeiertagDC { Datum = new DateTime ( year , 1 , 6 ) , Name = "Heilige Drei Könige" } ) ;
}
if ( bundesland . ToLower ( ) = = "nrw" | | bundesland . ToLower ( ) = = "bayern" )
2022-08-30 08:53:24 +02:00
list . Add ( new FeiertagDC { Datum = new DateTime ( year , 11 , 1 ) , Name = "Allerheiligen" } ) ;
2022-09-07 14:43:01 +02:00
2023-01-05 13:56:27 +01:00
2022-09-07 14:43:01 +02:00
list . Add ( new FeiertagDC { Datum = new DateTime ( year , 12 , 24 ) , Name = "Heilig Abend" } ) ; // Eigentlich kein gesetzlicher Feiertag, wird bei uns aber immer als Standard gesetzt, da in der Praxis die meisten Unternehmen einen halben für Heilig Abend und einen halben für Silvester geben.
2018-10-08 11:57:16 +02:00
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
2022-11-10 17:44:27 +01:00
list . AddRange ( GetDBFeiertage ( year ) ) ;
2017-06-11 16:01:01 +02:00
return list ;
}
2022-11-10 17:44:27 +01:00
2022-03-09 14:59:38 +01:00
//Für zentrale Ablage der Feiertage
2022-11-10 17:44:27 +01:00
public virtual List < FeiertagDC > GetDBFeiertage ( int year )
{
if ( databaseFeiertage = = null )
{
var feiertage = DAOFactory . GenericDAO . GetAll < Feiertag > ( ) ;
databaseFeiertage = MapperFactory . FeiertagDC_Feiertag . MapToNewDCs ( feiertage . Where ( f = > f . Datum > = new DateTime ( year , 1 , 1 ) & & f . Datum < new DateTime ( year + 1 , 1 , 1 ) ) ) ;
2022-03-09 14:59:38 +01:00
2022-11-10 17:44:27 +01:00
}
2022-03-09 14:59:38 +01:00
2022-11-10 17:44:27 +01:00
return databaseFeiertage ;
}
2017-06-11 16:01:01 +02:00
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 ;
2020-10-13 14:35:06 +02:00
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-08-04 15:13:15 +02:00
{
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
2022-08-30 08:53:24 +02:00
2021-09-14 14:08:08 +02:00
private void SetLokaleFeiertagListe ( int year )
{
_Feiertage = GetFeiertage ( year ) ;
}
2020-10-13 14:35:06 +02:00
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 ) ;
}
2022-08-30 08:53:24 +02:00
public virtual decimal GetFeiertagsFaktor ( DateTime start )
{
if ( IstFeiertag ( start ) )
{
return 1 ;
}
return 0 ;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ab hier Urlaubskontodarstellung etc.
////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-08-27 07:34:43 +02:00
public virtual List < UrlaubskontoDarstellungDC > BerechneUrlaubskontoZurDarstellung ( EmployeeDC emp , int year )
{
List < UrlaubskontoDarstellungDC > dcs = new List < UrlaubskontoDarstellungDC > ( ) ;
2021-09-06 12:43:23 +02:00
EmployeeServiceImp es = new EmployeeServiceImp ( ) ;
2021-09-14 14:08:08 +02:00
2021-09-14 16:52:17 +02:00
// Urlaubskonto erstellen
2021-09-14 14:08:08 +02:00
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 ) ;
2021-08-27 07:34:43 +02:00
// Benötigt werden:
2021-09-14 16:52:17 +02:00
// 1. Vetragliche Urlaubstage für´ s Jahr
2021-09-14 14:08:08 +02:00
List < ContractDC > contracts = new List < ContractDC > ( ) ;
2022-07-29 11:51:42 +02:00
Dictionary < ContractDC , int > contractsAndWeeklyDays = new Dictionary < ContractDC , int > ( ) ;
2021-09-14 16:52:17 +02:00
// Vertrag für Jahr raussuchen
foreach ( var c in emp . Contracts )
2021-08-27 07:34:43 +02:00
{
2021-09-06 12:43:23 +02:00
DateTime contractEndDate = new DateTime ( ) ;
if ( c . ContractEndDate = = null )
contractEndDate = new DateTime ( 2099 , 12 , 31 ) ;
else
contractEndDate = c . ContractEndDate . Value ;
2021-09-14 16:52:17 +02:00
if ( year > = c . EntryDate . Value . Year & & year < = contractEndDate . Year ) // Wenn das ausgewählte Jahr zwischen Vertragsbeginn und -ende liegt
2022-07-29 11:51:42 +02:00
{
2021-09-14 14:08:08 +02:00
contracts . Add ( c ) ;
2022-07-29 11:51:42 +02:00
contractsAndWeeklyDays . Add ( c , c . WeeklyDays ) ;
}
2021-08-27 07:34:43 +02:00
}
2021-09-14 14:08:08 +02:00
if ( contracts . Count = = 0 ) // Kein Vertrag = kein Urlaubskonto
2021-09-06 12:43:23 +02:00
return null ;
2021-09-14 14:08:08 +02:00
2021-09-14 16:52:17 +02:00
// 2. Abzuziehende Tage wegen Vertragsbeginn mitten im Jahr
2022-07-29 11:51:42 +02:00
foreach ( var contractAndWeeklyDays in contractsAndWeeklyDays )
2021-08-27 07:34:43 +02:00
{
2022-07-29 11:51:42 +02:00
var contract = contractAndWeeklyDays . Key ;
2021-09-15 11:00:00 +02:00
#region Vielleicht bald unnötig
2021-09-14 16:52:17 +02:00
// Zahlen für Darstellung in View
2021-09-14 14:08:08 +02:00
decimal tageNachAbzug = 0 ;
decimal abzuziehendeTage = 0 ;
2021-08-27 07:34:43 +02:00
2021-10-18 00:43:47 +02:00
int arbeitstage = contract . WeeklyDays ; // Vertragliche Arbeitstage
2021-09-14 16:52:17 +02:00
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
2021-09-14 14:08:08 +02:00
{
2021-09-14 16:52:17 +02:00
if ( contract . EntryDate . Value . Year = = year ) // Wenn Vertrag im gewählten Jahr beginnt
2021-09-14 14:08:08 +02:00
{
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 ) ;
}
}
2021-09-14 16:52:17 +02:00
else if ( endDate . Value . Year = = year ) // Wenn Vertrag im gewählten Jahr endet
2021-09-14 14:08:08 +02:00
{
int restlicheTageImJahr = Convert . ToInt32 ( ( ( DateTime ) endDate - new DateTime ( year , 1 , 1 ) ) . TotalDays ) ;
tageNachAbzug = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation ( ( DateTime ) contract . EntryDate , endDate , arbeitstage , restlicheTageImJahr , leaveDays ) ;
}
2021-09-14 16:52:17 +02:00
// Abzuziehende Tage = Vertragliche Urlaubstage - Tage, die nach Abzug der verfallenden Tage übrig bleiben
2021-09-14 14:08:08 +02:00
abzuziehendeTage = ( decimal ) leaveDays - tageNachAbzug ;
}
2021-09-15 11:00:00 +02:00
#endregion
2021-09-14 14:08:08 +02:00
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 ;
2021-09-14 14:08:08 +02:00
var obereZeile = new UrlaubskontoDarstellungDC ( )
{
2021-10-18 00:43:47 +02:00
AnzahlTage = string . Format ( "{0:0.00}" , anzahlTage ) ,
2021-09-14 14:08:08 +02:00
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 ) ;
2021-09-15 11:12:01 +02:00
#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
2021-09-14 14:08:08 +02:00
}
2021-09-06 12:43:23 +02:00
2021-09-14 16:52:17 +02:00
// 3. Geschenkte Urlaubstage im Jahr
2021-09-06 12:43:23 +02:00
if ( geschenkteUrlaubstage . Count > 0 & & geschenkteUrlaubstage . Any ( g = > g . Date . Year = = year ) )
{
2021-09-14 14:08:08 +02:00
// Einen Eintrag pro geschenktem Urlaubstag
2021-09-06 12:43:23 +02:00
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
} ) ;
}
}
}
2021-09-14 16:52:17 +02:00
// 4. Verfallener Resturlaub
// Verfallsdatum der Urlaubstage des letzten Jahres zur Darstellung (also ohne Uhrzeit)
2021-09-06 12:43:23 +02:00
var expDate = GetExpirationDate ( year ) . ToString ( ) . Split ( ' ' ) ;
2021-08-27 07:34:43 +02:00
2021-09-06 12:43:23 +02:00
// Resturlaub und den verbleibenden Resturlaub nach Verfall erstellen
2023-03-06 13:39:58 +01:00
if ( aktuellesKonto . Value . ResturlaubVorjahrTotal > 0 ) // Wenn Urlaub aus dem Vorjahr mitgenommen wurde
2021-08-27 07:34:43 +02:00
{
2021-09-06 12:43:23 +02:00
dcs . Add ( new UrlaubskontoDarstellungDC ( )
{
2021-09-14 14:08:08 +02:00
Erlaeuterung = "Resturlaub aus " + ( year - 1 ) + " :" ,
AnzahlTage = string . Format ( "+{0:0.00}" , aktuellesKonto . Value . ResturlaubVorjahrTotal ) ,
2021-09-06 12:43:23 +02:00
Herkunft = string . Format ( "EmpOid:{0} Urlaubskonto:{1}" , emp . EmployeeOid , year ) ,
Tooltip = null ,
IsDeletable = false
} ) ;
}
2023-03-06 13:39:58 +01:00
if ( aktuellesKonto . Value . VerfallenerUrlaub > 0 ) // Wenn Urlaubstage verfallen sind
2021-09-06 12:43:23 +02:00
{
2021-09-14 14:08:08 +02:00
dcs . Add ( new UrlaubskontoDarstellungDC ( )
2021-09-06 12:43:23 +02:00
{
2021-09-14 14:08:08 +02:00
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
} ) ;
2021-09-06 12:43:23 +02:00
}
2021-08-27 07:34:43 +02:00
2021-09-14 16:52:17 +02:00
// 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
{
2021-09-06 12:43:23 +02:00
// Urlaube durchgehen und die Tage zählen
2021-09-14 14:08:08 +02:00
foreach ( var spanne in absences )
2021-09-06 12:43:23 +02:00
{
decimal summeTage = 0 ;
2021-09-14 16:52:17 +02:00
#region Urlaubstage zählen
if ( spanne . End = = null ) // Wenn es kein Ende gibt, Ende auf letzten Tag im Jahr setzen
2021-09-06 12:43:23 +02:00
spanne . End = new DateTime ( year , 12 , 31 ) ;
2021-09-14 16:52:17 +02:00
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
2021-09-06 12:43:23 +02:00
summeTage + + ;
2022-11-10 17:44:27 +01:00
else if ( spanne . Start . Value . Date = = spanne . End . Value . Date & & spanne . Start . Value . TimeOfDay ! = spanne . End . Value . TimeOfDay ) // ein halber Tag Urlaub
2021-09-22 15:34:38 +02:00
summeTage + = 0.5 m ;
2021-09-14 16:52:17 +02:00
else // Mehr als ein Tag Urlaub
2021-09-06 12:43:23 +02:00
{
DateTime startForLoop = ( spanne . Start . Value . Year = = year ) ? spanne . Start . Value : new DateTime ( year , 1 , 1 ) ;
2021-09-14 16:52:17 +02:00
// 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
2022-08-02 07:52:34 +02:00
#region neu
// Variable wird für jeden Tag hochgezählt und resettet, sobald wieder Montag ist. So kann vermieden werden, dass bei einer Arbeitswoche von unter 5 Tagen trotzdem 5 Tage Urlab abgezogen werden
var tageInDerWoche = 0 ;
#endregion
2021-09-22 15:34:38 +02:00
while ( startForLoop < = spanne . End . Value )
2021-09-06 12:43:23 +02:00
{
2022-08-02 07:52:34 +02:00
if ( startForLoop . DayOfWeek = = DayOfWeek . Monday )
tageInDerWoche = 0 ;
2022-07-29 11:51:42 +02:00
var currentContract = contractsAndWeeklyDays . FirstOrDefault ( c = > startForLoop > = c . Key . EntryDate & & startForLoop < = c . Key . ContractEndDate | | startForLoop > = c . Key . EntryDate & & c . Key . ContractEndDate = = null ) ;
if ( currentContract . Key = = null )
{
if ( startForLoop . DayOfWeek ! = DayOfWeek . Saturday & & startForLoop . DayOfWeek ! = DayOfWeek . Sunday & & ! _Feiertage . Contains ( startForLoop ) )
summeTage + + ;
}
else
{
2022-08-02 07:52:34 +02:00
if ( ! CheckIstWochenende ( currentContract . Value , startForLoop . DayOfWeek ) & & ! IstFeiertag ( startForLoop ) & & tageInDerWoche < currentContract . Value )
{
2022-07-29 11:51:42 +02:00
summeTage + + ;
2022-08-02 07:52:34 +02:00
tageInDerWoche + + ;
}
2022-07-29 11:51:42 +02:00
}
2021-08-27 07:34:43 +02:00
2021-09-06 12:43:23 +02:00
startForLoop = startForLoop . AddDays ( 1 ) ;
}
}
2021-09-14 14:08:08 +02:00
#endregion
2021-09-06 12:43:23 +02:00
2021-09-14 16:52:17 +02:00
// Start- und Enddatum des Urlaubs für Darstellung vorbereiten
2021-09-06 12:43:23 +02:00
var startAsArray = spanne . Start . Value . ToString ( ) . Split ( ' ' ) ;
var endAsArray = spanne . End . Value . ToString ( ) . Split ( ' ' ) ;
2021-09-14 16:52:17 +02:00
// Eintrag für Urlaubstag setzen (Erläuterung abhängig davon, ob Urlaub nur ein Tag geht oder über mehrere
2021-09-06 12:43:23 +02:00
dcs . Add ( new UrlaubskontoDarstellungDC ( )
{
2022-11-10 17:44:27 +01:00
Erlaeuterung = startAsArray [ 0 ] = = endAsArray [ 0 ] ? string . Format ( "Urlaub genommen am {0}" , startAsArray [ 0 ] ) :
2021-09-14 14:08:08 +02:00
string . Format ( "Urlaub genommen vom {0} bis {1}" , startAsArray [ 0 ] , endAsArray [ 0 ] ) ,
2021-09-06 12:43:23 +02:00
AnzahlTage = string . Format ( "-{0:0.00}" , summeTage ) ,
2022-11-10 17:44:27 +01:00
AnzahlTageUrlaub = summeTage ,
2021-09-06 12:43:23 +02:00
Herkunft = string . Format ( "AbsenceOid: {0}" , spanne . AbsenceTimeOid ) ,
2021-09-14 14:08:08 +02:00
Tooltip = spanne . Notice ,
2021-09-06 12:43:23 +02:00
IsDeletable = false ,
DatumZurSortierung = spanne . Start . Value
} ) ;
}
}
2021-08-27 07:34:43 +02:00
2021-09-14 16:52:17 +02:00
// 6. Anzahl der aus 1.-5. resultierenden Resturlaubstage fürs Jahr, also Resturlaub vom Urlaubskonto
2023-03-06 13:39:58 +01:00
var anzTage = aktuellesKonto . Value . ResturlaubVorjahrTotal > 0 & & aktuellesKonto . Value . VerfallenerUrlaub < = 0 ? aktuellesKonto . Value . Resturlaub + aktuellesKonto . Value . ResturlaubVorjahr : aktuellesKonto . Value . Resturlaub ;
2021-09-14 16:52:17 +02:00
dcs . Add ( new UrlaubskontoDarstellungDC ( )
2021-09-06 12:43:23 +02:00
{
2023-03-06 13:39:58 +01:00
AnzahlTage = string . Format ( "={0:0.00}" , anzTage ) ,
2021-09-06 12:43:23 +02:00
Erlaeuterung = "Summe der verbleibenden Urlaubstage: " ,
Herkunft = "UrlaubskontoEmpOid" + aktuellesKonto . Value . EmployeeOid ,
Tooltip = null ,
IsDeletable = false ,
DatumZurSortierung = new DateTime ( 2999 , 12 , 31 )
2021-09-14 16:52:17 +02:00
} ) ;
2021-09-06 12:43:23 +02:00
2021-09-14 16:52:17 +02:00
//Liste der DCs nach Datum sortieren, um eine zeitliche Hierarchie zu schaffen
2021-09-06 12:43:23 +02:00
var sortierteDCs = dcs . OrderBy ( dc = > dc . DatumZurSortierung ) . ToList ( ) ;
2021-08-27 07:34:43 +02:00
2021-09-06 12:43:23 +02:00
return sortierteDCs ;
2021-08-27 07:34:43 +02:00
}
2020-10-13 14:35:06 +02:00
public virtual Dictionary < int , UrlaubskontoDC > BerechneUrlaubskonto ( Employee emp , int year )
{
try
{
2021-09-14 14:08:08 +02:00
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
2020-10-13 14:35:06 +02:00
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 ( ) ;
2021-06-10 14:40:23 +02:00
2020-10-13 14:35:06 +02:00
// 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
2020-10-13 14:35:06 +02:00
var konten = new Dictionary < int , UrlaubskontoDC > ( ) ;
for ( int i = firstYear ; i < = year ; i + + )
{
konten . Add ( i , new UrlaubskontoDC ( ) ) ;
}
2022-07-29 11:51:42 +02:00
int? workdays = 0 ;
2020-10-13 14:35:06 +02:00
// Jahresurlaubanspruch berechnen
foreach ( var contract in emp . Contracts )
{
var start = contract . EntryDate ? . Year ? ? firstYear ;
var end = contract . ContractEndDate ? . Year ? ? year ;
2022-07-29 11:51:42 +02:00
if ( year > = start & & year < = end )
workdays = contract . WeeklyDays ;
2021-09-15 11:00:00 +02:00
// Durch jedes Jahr des Vertrags gehen
2020-10-13 14:35:06 +02:00
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-09-14 14:08:08 +02:00
2021-10-18 00:43:47 +02:00
if ( contract . EmploymentType ? . LeaveDays ! = null )
2021-08-04 15:13:15 +02:00
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 ;
2021-08-04 15:13:15 +02:00
int arbeitstage = contract . WeeklyDays ! = null ? ( int ) contract . WeeklyDays : 0 ;
DateTime ? endDate = contract . ContractEndDate = = null ? new DateTime ( year , 12 , 31 ) : contract . ContractEndDate ;
2022-03-25 15:05:39 +01:00
if ( contract ! = null & & contract . EntryDate ! = null )
2021-08-04 15:13:15 +02:00
{
2022-03-25 15:05:39 +01:00
if ( contract . EntryDate . Value . Year = = i | | endDate . Value . Year = = i ) // Endet oder beginnt Vertrag in gewähltem Jahr // HIER IST DAS PROBLEM
2021-08-04 15:13:15 +02:00
{
2022-03-25 15:05:39 +01:00
decimal errechneteTage = 0 ;
decimal weggefallen = 0 ;
if ( contract . EntryDate . Value . Year = = i )
2021-09-14 14:08:08 +02:00
{
2022-03-25 15:05:39 +01:00
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 ) ;
}
2021-09-14 14:08:08 +02:00
}
2022-03-25 15:05:39 +01:00
else if ( endDate . Value . Year = = i )
2021-09-14 14:08:08 +02:00
{
2022-03-25 15:05:39 +01:00
int restlicheTageImJahr = Convert . ToInt32 ( ( ( DateTime ) endDate - new DateTime ( i , 1 , 1 ) ) . TotalDays ) ;
errechneteTage + = CalcCorrectNumberOfLeaveDaysForSpecialContractSituation ( ( DateTime ) contract . EntryDate , endDate , arbeitstage , restlicheTageImJahr , urlaubsanspruchFuerVertragInLoop ) ;
2021-09-14 14:08:08 +02:00
}
2022-03-25 15:05:39 +01:00
// Resturlaub und Urlaubsanspruch auf errechnete Werte setzen
weggefallen = urlaubsanspruchFuerVertragInLoop - errechneteTage ;
tmp . Resturlaub + = errechneteTage ;
tmp . Urlaubsanspruch + = urlaubsanspruchFuerVertragInLoop - weggefallen ;
2021-08-04 15:13:15 +02:00
}
2022-03-25 15:05:39 +01:00
else
2021-08-04 15:13:15 +02:00
{
2022-03-25 15:05:39 +01:00
tmp . Urlaubsanspruch + = urlaubsanspruchFuerVertragInLoop ;
tmp . Resturlaub = tmp . Urlaubsanspruch ;
2021-08-04 15:13:15 +02:00
}
}
2022-03-25 15:05:39 +01:00
2021-01-12 01:12:03 +01:00
}
2020-10-13 14:35:06 +02:00
}
}
2021-09-15 11:00:00 +02:00
// Abwesenheiten in Jahr x zu einem Dictionary hinzufügen
2020-10-13 14:35:06 +02:00
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 ( ) ;
2021-09-14 14:08:08 +02:00
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
2020-10-13 14:35:06 +02:00
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
2020-10-13 14:35:06 +02:00
while ( yearFiller < absYear )
{
var tmp = konten [ yearFiller ] ;
var tmp2 = konten [ yearFiller + 1 ] ;
tmp2 . ResturlaubVorjahrTotal = tmp . Resturlaub ;
tmp2 . ResturlaubVorjahr = tmp . Resturlaub ;
yearFiller + + ;
}
2021-08-04 15:13:15 +02:00
2020-10-13 14:35:06 +02:00
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
2021-09-14 14:08:08 +02:00
var start = DateTimeExtensions . GetMax ( absence . Start , new DateTime ( absYear , 1 , 1 ) ) ;
2020-10-13 14:35:06 +02:00
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
2022-07-29 11:51:42 +02:00
var dauer = BerechneAnzahlUrlaubstage ( absence , null , absYear , workdays ) ; // HIER MÜSSEN PARAMETER FÜR ISTWOCHENENDE() MITGEGEBEN WERDEN
2021-09-15 11:00:00 +02:00
// Verfallsdatum des Urlaubs festlegen
2021-09-14 15:29:17 +02:00
var expiration = GetExpirationDate ( absYear ) ;
2021-06-18 13:34:42 +02:00
current . UrlaubsVerfallsdatum = expiration ;
2020-10-13 14:35:06 +02:00
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
2020-10-13 14:35:06 +02:00
if ( current . ResturlaubVorjahr > 0 & & start < = expiration )
{
2021-09-14 14:08:08 +02:00
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 ;
2021-09-14 14:08:08 +02:00
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
2021-09-14 14:08:08 +02:00
while ( zaehlerDatum < = firstEnd )
{
2022-07-29 11:51:42 +02:00
bool istWochenende = CheckIstWochenende ( workdays , zaehlerDatum . DayOfWeek ) ;
if ( ! istWochenende & & ! _Feiertage . Contains ( zaehlerDatum ) )
2021-09-14 14:08:08 +02:00
dauerVorjahr + + ;
zaehlerDatum = zaehlerDatum . AddDays ( 1 ) ;
}
2021-08-04 15:13:15 +02:00
2020-10-13 14:35:06 +02:00
var bucheVorjahr = Math . Min ( current . ResturlaubVorjahr , dauerVorjahr ) ;
current . ResturlaubVorjahr - = bucheVorjahr ;
dauer - = bucheVorjahr ;
2021-09-14 14:08:08 +02:00
if ( dauer < 0 )
{
if ( ! zuVerfallZuAddieren . ContainsKey ( absYear ) )
zuVerfallZuAddieren . Add ( absYear , 0 ) ;
zuVerfallZuAddieren [ absYear ] - = dauer ;
}
2020-10-13 14:35:06 +02:00
}
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
2021-06-18 13:34:42 +02:00
{
2021-09-14 14:08:08 +02:00
current . VerfallenerUrlaub = zuVerfallZuAddieren . ContainsKey ( absYear ) ? current . ResturlaubVorjahr + zuVerfallZuAddieren [ absYear ] : current . ResturlaubVorjahr ;
2021-06-18 13:34:42 +02:00
}
2020-10-13 14:35:06 +02:00
// Restliche Dauer vom Urlaub abziehen
2021-09-14 14:08:08 +02:00
current . Resturlaub - = dauer < 0 ? 0 : dauer ; // ausprobieren
2020-10-13 14:35:06 +02:00
}
2021-09-14 14:08:08 +02:00
// 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-14 14:08:08 +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
2021-09-14 14:08:08 +02:00
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.0 m ;
2021-09-14 14:08:08 +02:00
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 ;
2021-09-14 14:08:08 +02:00
}
}
2020-10-13 14:35:06 +02:00
return konten ;
}
catch ( Exception e )
{
throw e ;
}
}
2021-01-12 01:12:03 +01:00
2022-07-29 11:51:42 +02:00
private bool CheckIstWochenende ( int? workdays , DayOfWeek tag )
{
bool istWochenende = tag = = DayOfWeek . Saturday | | tag = = DayOfWeek . Sunday ;
if ( workdays = = 6 )
istWochenende = tag = = DayOfWeek . Sunday ;
else if ( workdays > 6 )
istWochenende = false ;
return istWochenende ;
}
2022-04-05 12:26:24 +02:00
internal decimal BerechneAnzahlUrlaubstageMitWeeklyDays ( AbsenceTimeDC absenceDC , int year , int weeklyDays )
{
decimal tage = 0 ;
if ( absenceDC . Start . HasValue )
{
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 ;
}
decimal tageInEinerWoche = 0 ; // Tage für die Ist- und Sollstunden
int wochentageVergangen = 0 ; // Vergangene Wochentage
while ( start < = end )
{
// Wenn Wochentag Montag ist, werden Tage einer Woche resetted und die vergangenen Arbeitstage
var wochentag = start . DayOfWeek ;
if ( wochentag = = DayOfWeek . Monday )
{
tageInEinerWoche = 0 ;
wochentageVergangen = 0 ;
}
if ( ! IstFeiertag ( start ) )
{
if ( wochentageVergangen < weeklyDays )
{
2022-04-12 12:14:21 +02:00
// Wenn nur ein halber Tag, dann..
2022-04-05 12:26:24 +02:00
if ( start . Date = = end . Date & & start . TimeOfDay ! = end . TimeOfDay )
{
tageInEinerWoche + = 0.5 m ;
if ( tageInEinerWoche > = weeklyDays )
tage + = tageInEinerWoche > weeklyDays ? 0 - tage + weeklyDays : 0.5 m ;
else
tage + = 0.5 m ;
}
else
{
tageInEinerWoche + + ;
if ( tageInEinerWoche > = weeklyDays )
tage + = tageInEinerWoche > weeklyDays ? 0 - tage + weeklyDays : 1 ;
else
tage + + ;
}
}
2022-04-12 12:14:21 +02:00
wochentageVergangen + + ;
2022-04-05 12:26:24 +02:00
}
start = start . AddDays ( 1 ) ;
}
}
return tage ;
}
2021-09-14 16:52:17 +02: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
2021-08-04 15:13:15 +02:00
private decimal CalcCorrectNumberOfLeaveDaysForSpecialContractSituation ( DateTime entryDate , DateTime ? endDate , int anzahlArbeitstage , int restlicheTageImJahr , decimal? urlaubstageProJahr )
{
decimal urlaubstage = 0 ;
if ( urlaubstageProJahr = = null )
urlaubstageProJahr = 0 m ;
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 )
2021-09-14 14:08:08 +02:00
urlaubstage = ( decimal ) urlaubstageProJahr ;
2021-09-14 16:52:17 +02:00
2021-09-14 14:08:08 +02:00
else if ( endDate . Value . Day = = 31 & & endDate . Value . Month = = 12 )
urlaubstage = ( decimal ) urlaubstageProJahr ;
2021-09-14 16:52:17 +02:00
2021-08-04 15:13:15 +02:00
else
{
if ( anzahlArbeitstage < 5 ) // weniger als 5 Tage
urlaubstage = ( decimal ) urlaubstageProJahr / 5 m * anzahlArbeitstage ;
else
{
if ( anzahlArbeitstage = = 5 ) // 5 Tage
urlaubstage = ( decimal ) urlaubstageProJahr / 365 m * restlicheTageImJahr ;
else if ( anzahlArbeitstage = = 6 ) // 6 Tage
urlaubstage = ( decimal ) urlaubstageProJahr / 365 m * restlicheTageImJahr ;
}
}
}
else if ( /*entryDate.Day > 1 && */ anzahlArbeitstage < 5 ) // Mitten im Jahr, weniger als 5 Tage
{
urlaubstage = ( decimal ) urlaubstageProJahr / 5 m * 3 m / 365 m * restlicheTageImJahr ;
}
else if ( /*entryDate.Day > 1 && */ anzahlArbeitstage > = 5 ) // Mitten im Jahr, 5 oder 6 Tage
{
urlaubstage = ( decimal ) urlaubstageProJahr / 365 m * restlicheTageImJahr ;
}
// Runden
if ( urlaubstage - ( int ) urlaubstage < = 0.1 m )
{
urlaubstage = Math . Round ( urlaubstage , MidpointRounding . AwayFromZero ) ;
}
else if ( urlaubstage - ( int ) urlaubstage < = 0.5 m )
{
decimal digits = urlaubstage - ( int ) urlaubstage ;
urlaubstage = urlaubstage - digits + 0.5 m ;
}
else if ( urlaubstage - ( int ) urlaubstage < = 1.0 m )
{
urlaubstage = Math . Ceiling ( urlaubstage ) ;
}
return urlaubstage ;
}
2022-07-29 11:51:42 +02:00
public decimal BerechneAnzahlUrlaubstage ( AbsenceTime absence , AbsenceTimeDC absenceDC , int year , int? workdays )
2021-01-12 01:12:03 +01:00
{
2021-10-12 16:00:17 +02:00
if ( absence ! = null )
2021-01-12 01:12:03 +01:00
{
2021-10-12 16:00:17 +02:00
if ( absence . Start . HasValue )
2021-09-06 12:43:23 +02:00
{
2021-10-12 16:00:17 +02:00
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 ;
}
2021-09-06 12:43:23 +02:00
2021-10-12 16:00:17 +02:00
if ( maxend < end )
{
end = maxend ;
}
2021-09-06 12:43:23 +02:00
2022-08-02 07:52:34 +02:00
var tageInDerWoche = 0 m ;
2021-10-12 16:00:17 +02:00
while ( start < = end )
{
2022-08-02 07:52:34 +02:00
if ( start . DayOfWeek = = DayOfWeek . Monday )
tageInDerWoche = 0 ;
if ( ! CheckIstWochenende ( workdays , start . DayOfWeek ) & & ! IstFeiertag ( start ) & & tageInDerWoche < workdays . Value & & tageInDerWoche + 1 < = workdays . Value )
2021-10-12 16:00:17 +02:00
{
if ( start . Date = = end . Date & & start . TimeOfDay ! = end . TimeOfDay )
2022-08-02 07:52:34 +02:00
{
2021-10-12 16:00:17 +02:00
days + = 0.5 m ;
2022-08-02 07:52:34 +02:00
tageInDerWoche + = 0.5 m ;
}
2021-10-12 16:00:17 +02:00
else
2022-08-02 07:52:34 +02:00
{
2021-10-12 16:00:17 +02:00
days + + ;
2022-08-02 07:52:34 +02:00
tageInDerWoche + + ;
}
2021-10-12 16:00:17 +02:00
}
start = start . AddDays ( 1 ) ;
}
return ( decimal ) days ;
}
}
else if ( absenceDC ! = null )
{
if ( absenceDC . Start . HasValue )
2021-09-06 12:43:23 +02:00
{
2021-10-12 16:00:17 +02:00
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 )
2021-09-06 12:43:23 +02:00
{
2021-10-12 16:00:17 +02:00
end = absenceDC . End . Value ;
2021-09-06 12:43:23 +02:00
}
2021-10-12 16:00:17 +02:00
if ( maxend < end )
{
end = maxend ;
}
while ( start < = end )
{
2022-07-29 11:51:42 +02:00
if ( ! CheckIstWochenende ( workdays , start . DayOfWeek ) & & ! IstFeiertag ( start ) )
2021-10-12 16:00:17 +02:00
{
if ( start . Date = = end . Date & & start . TimeOfDay ! = end . TimeOfDay )
days + = 0.5 m ;
else
days + + ;
}
start = start . AddDays ( 1 ) ;
}
return ( decimal ) days ;
2021-09-06 12:43:23 +02:00
}
}
2021-10-12 16:00:17 +02:00
2021-09-06 12:43:23 +02:00
return 0 ;
}
2021-09-15 14:32:21 +02:00
public Dictionary < long? , decimal > BerechneAnzEinerAbwesenheitFuerMehrereMitarbeiter ( List < long? > empOids , int year , string reason )
2021-09-06 12:43:23 +02:00
{
2021-09-15 14:32:21 +02:00
SetLokaleFeiertagListe ( year ) ;
2021-09-06 12:43:23 +02:00
2021-09-15 14:32:21 +02:00
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
2021-09-15 14:32:21 +02:00
Dictionary < long? , decimal > urlaubGenommenProMitarbeiter = new Dictionary < long? , decimal > ( ) ;
2021-01-12 01:12:03 +01:00
2021-09-15 14:32:21 +02:00
foreach ( var oid in empOids )
{
var absencesForCurrentEmp = absences . Where ( a = > a . EmployeeOid = = oid ) ;
decimal tage = 0 ;
2021-08-04 15:13:15 +02:00
2021-09-15 14:32:21 +02:00
foreach ( var abs in absencesForCurrentEmp )
2021-01-12 01:12:03 +01:00
{
2021-09-15 14:32:21 +02: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
{
2021-09-15 14:32:21 +02: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.5 m ;
else
tage + + ;
}
2021-01-12 01:12:03 +01:00
2021-09-15 14:32:21 +02:00
start = start . AddDays ( 1 ) ;
}
2021-01-12 01:12:03 +01:00
}
2021-09-15 14:32:21 +02:00
urlaubGenommenProMitarbeiter . Add ( oid , tage ) ;
2021-01-12 01:12:03 +01:00
}
2021-09-15 14:32:21 +02:00
return urlaubGenommenProMitarbeiter ;
2021-01-12 01:12:03 +01:00
}
2020-10-13 14:35:06 +02:00
}
2021-06-10 14:40:23 +02:00
}