754 lines
37 KiB
C#
754 lines
37 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text.RegularExpressions;
|
||
using BeWo.Data.Access;
|
||
using BeWo.Data.Entities;
|
||
using BeWo.Service.DCEntityMapper;
|
||
using 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;
|
||
}
|
||
}
|
||
}
|