Files
BeWoPlaner/Service/Dienstplanung/DienstplanungsManager.cs

1978 lines
94 KiB
C#

using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Configuration;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Plugins;
using BeWo.Service.ServiceImplementations;
using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace BeWo.Service.Dienstplanung
{
public class DienstplanungsManager
{
public virtual DienstplanerRootDC BuildDienstplanerRootObject(DateTime date, long wohnheimOid)
{
var anzahlZeilen = AppSettings.CreateSettings().DienstplanungStandardZeilenAnzahl;
var wh = DAOFactory.GenericDAO.GetByID<Wohnheim>(wohnheimOid);
DienstplanerRootDC root = new DienstplanerRootDC();
OperationsServiceImp os = new OperationsServiceImp();
DienstplanungsManager manager = PluginLoader.FindClass<DienstplanungsManager>();
root.EnableDiensteAnFeiertagen = manager.SetEnableDiensteAnFeiertagen();
root.EnableAbwesenheitenAnWochenenden = manager.SetEnableAbwesenheitenAnWochenenden();
root.EnableSorting = SetEnableSorting();
root.SortierMethoden = SetSortierMethoden();
root.ZeitraumFuerPflichtbesetzungStart = new DateTime(2000, 01, 01, 0, 0, 0);
root.ZeitraumFuerPflichtbesetzungEnde = new DateTime(2000, 01, 01, 0, 0, 0);
#if DEBUG
TimeSpan start, ende;
start = wh.PflichtbesetzungStart.IsNullOrEmpty() ? new TimeSpan(0, 0, 0) : TimeSpan.Parse(wh.PflichtbesetzungStart);
ende = wh.PflichtbesetzungEnde.IsNullOrEmpty() ? new TimeSpan(0, 0, 0) : TimeSpan.Parse(wh.PflichtbesetzungEnde);
root.ZeitraumFuerPflichtbesetzungStart = new DateTime(2000, 01, 01, start.Hours, start.Minutes, 0);
root.ZeitraumFuerPflichtbesetzungEnde = new DateTime(2000, 01, 01, ende.Hours, ende.Minutes, 0);
#endif
root.AlleDienste = GetAllDienste(wohnheimOid).OrderBy(d => d.Start).ToList();
root.AlleDienste.Insert(0, DienstInfoDC.Platzhalter);
root.AbsenceTimes = GetAbsenceTimeVacationByWohnheim(wohnheimOid, date.Year, date.Month);
root.OverTimes = GetOverTimesByWohnheim(wohnheimOid, date.Year, date.Month);
root.RegelmaessigeDienste = GetRegelmaessigeDienste(wohnheimOid);
root.TextBoxForeColor = GetColorForForeground();
root.AlleDienstEintraege = GetAllDienstEintraegeAsList(wohnheimOid, date.Year, date.Month);
#region Dienste, die eigentlich Einträge sind, aber irgendwie in Vertretungen gelandet sind, in die richtige Tabelle verschieben
var emps = new List<Employee>();
foreach (var e in wh.Employee2WohnheimList)
emps.Add(e.Employee);
List<DienstEintrag> eintraegeToInsert = new List<DienstEintrag>();
List<Dienstvertretung> falscheVertretungen = new List<Dienstvertretung>();
var vertretungen = DAOFactory.GenericDAO.GetAllActive<Dienstvertretung>().Where(v => v.WohnheimOid == wh.Oid);
foreach (var emp in emps)
{
falscheVertretungen = vertretungen.Where(v => v.EmployeeOid == emp.Oid && v.WohnheimOid == wh.Oid).ToList();
if (falscheVertretungen != null)
{
foreach (var vertretung in falscheVertretungen)
{
if (!root.AlleDienstEintraege.Any(e => e.Zeile == vertretung.Zeile && e.EmployeeOid == vertretung.EmployeeOid && e.WohnheimOid == vertretung.WohnheimOid))
{
var eintrag = new DienstEintrag()
{
Datum = vertretung.Datum,
DauerInStunden = vertretung.DauerInStunden,
DienstOid = vertretung.DienstOid,
EmployeeOid = vertretung.EmployeeOid,
Endzeit = vertretung.Endzeit,
IsActive = vertretung.IsActive,
Notice = vertretung.Notice,
Startzeit = vertretung.Startzeit,
Version = vertretung.Version,
WohnheimOid = vertretung.WohnheimOid,
Zeile = vertretung.Zeile
};
eintraegeToInsert.Add(eintrag);
}
}
}
}
if (eintraegeToInsert.Count > 0)
{
DAOFactory.GenericDAO.Insert(eintraegeToInsert);
DAOFactory.GenericDAO.Deactivate(falscheVertretungen);
}
#endregion
foreach (var rd in root.RegelmaessigeDienste)
root.AlleDienstEintraege.AddRange(AddRegelmaessigeDiensteToDienstplaner(rd, root.AlleDienstEintraege, root.AlleDienstvertretungen, root.AbsenceTimes, root.Feiertage,
root.EnableDiensteAnFeiertagen, root.DienstZeilenListe, root.ZeitraumFuerPflichtbesetzungStart, root.ZeitraumFuerPflichtbesetzungEnde, root.EnableStatuszeile, date));
foreach (var e in root.AlleDienstEintraege)
{
if (String.IsNullOrEmpty(e.Startzeit) || String.IsNullOrEmpty(e.Endzeit))
{
var d = root.AlleDienste.FirstOrDefault(a => a.Oid == e.DienstOid);
if (d != null)
{
if (String.IsNullOrEmpty(e.Startzeit))
{
e.Startzeit = String.Format("{0:HH:mm}", d.Start);
}
if (String.IsNullOrEmpty(e.Endzeit))
{
e.Endzeit = String.Format("{0:HH:mm}", d.Ende);
}
}
}
}
root.AlleDienstvertretungen = GetAllDienstvertretungenAsList(wohnheimOid, date.Year, date.Month);
//var eintraegeAndrianarivo = root.AlleDienstEintraege.Where(dv => dv.EmployeeOid == 36).ToList(); // debug
//var vertretungenAndrianarivo = root.AlleDienstvertretungen.Where(dv => dv.EmployeeOid == 36).ToList(); // debug
root.DienstDCListe = GetDienstEintraege(wohnheimOid, date.Year, date.Month); //BP
var dienstvertretungen = GetDienstvertretungen(wohnheimOid, date.Year, date.Month); // Hier muss dringend eingebaut werden, dass bereits enthaltene Mitarbeiter ignoriert oder verrechnet werden
//var dienstvertretungenAndrianarivo = dienstvertretungen.Where(dv => dv.Employee.EmployeeOid == 36).ToList(); // debug
foreach (var dv in dienstvertretungen)
{
if (!root.DienstDCListe.Any(dc => dc.Employee.EmployeeOid == dv.Employee.EmployeeOid))
root.DienstDCListe.Add(dv);
}
if (wh.Sortierungsart == 0) // Alphabetisch
{
if (wh.AbsteigendeSortierung == 0)
root.DienstDCListe = root.DienstDCListe.OrderBy(d => d.Employee.LastName).ToList();
else
root.DienstDCListe = root.DienstDCListe.OrderByDescending(d => d.Employee.LastName).ToList();
}
else if (wh.Sortierungsart == 1) // Anzahl der Dienste
{
Dictionary<long?, int> diensteProMitarbeiter = new Dictionary<long?, int>();
foreach (var elem in root.DienstDCListe)
{
if (!diensteProMitarbeiter.ContainsKey(elem.Employee.EmployeeOid))
diensteProMitarbeiter.Add(elem.Employee.EmployeeOid, 0);
foreach (var dict in elem.DienstDictArray)
diensteProMitarbeiter[elem.Employee.EmployeeOid] += dict.Count;
}
IOrderedEnumerable<KeyValuePair<long?, int>> diensteProMitarbeiterSortiert;
if (wh.AbsteigendeSortierung == 0)
diensteProMitarbeiterSortiert = diensteProMitarbeiter.OrderBy(d => d.Value);
else
diensteProMitarbeiterSortiert = diensteProMitarbeiter.OrderByDescending(d => d.Value);
var sortierteDienstDCListe = new List<DienstBlockDC>();
foreach (var emp in diensteProMitarbeiterSortiert)
{
var block = root.DienstDCListe.FirstOrDefault(dc => dc.Employee.EmployeeOid == emp.Key);
if (block != null)
sortierteDienstDCListe.Add(block);
}
root.DienstDCListe = sortierteDienstDCListe;
}
else if (wh.Sortierungsart == 2)
{
if (wh.AbsteigendeSortierung == 0)
root.DienstDCListe = root.DienstDCListe.OrderBy(d => d.Employee.LastName).ToList();
else
root.DienstDCListe = root.DienstDCListe.OrderByDescending(d => d.Employee.LastName).ToList();
}
root.EnableStatuszeile = Convert.ToBoolean(wh.PflichtbesetzungEinblenden);
root.DienstZeilenListe = new List<DienstZeileDC>();
if (root.EnableStatuszeile)
root.DienstZeilenListe.Add(InitStatusZeile(date));
root.DienstZeilenListe.AddRange(root.DienstDCListe //BP
.SelectMany(x => Init(x, root.AlleDienste, date, wh.StandardZeilenanzahl))
.ToList());
if (root.EnableStatuszeile)
{
var days = DateTime.DaysInMonth(date.Year, date.Month);
for (int i = 1; i <= days; i++)
{
root.DienstZeilenListe[0].StatusListe[i - 1].DauerhaftBesetztStatus = RefreshStatusForDay(root.AlleDienstEintraege,
root.AlleDienstvertretungen, i, root.ZeitraumFuerPflichtbesetzungStart, root.ZeitraumFuerPflichtbesetzungEnde);
}
}
root.StatusColorTrue = "#FF228B22";
root.StatusColorFalse = "#FFCD5C5C";
List<long> empOids = new List<long>();
#region EmployeeOids holen für Ist- und Saldoberechnung und die Liste der vorhandenen Mitarbeiter
// WIEDER EINKOMMENTIEREN FALLS FEHLER AUFTRETEN
//foreach (var item in wh.Employee2WohnheimList)
//{
// empOids.Add((long)item.EmployeeOid);
//}
//foreach (var item in root.AlleDienstvertretungen)
//{
// if (!empOids.Contains(item.EmployeeOid))
// empOids.Add((long)item.EmployeeOid);
//}
foreach (var item in root.DienstDCListe)
empOids.Add((long)item.Employee.EmployeeOid);
root.AllEmployee = new List<EmployeeDC>();
foreach (var block in root.DienstDCListe)
{
if (!root.AllEmployee.Contains(block.Employee))
root.AllEmployee.Add(block.Employee);
}
#endregion
var vs = PluginLoader.FindClass<VacationService>();
var feiertageDaten = vs.GetFeiertage(date.Year);
root.Feiertage = new List<FeiertagDC>();
foreach (var datum in feiertageDaten)
root.Feiertage.Add(vs.GetFeiertag(datum));
root.MonatsZusammenfassung = BerechneSollSaldoUndIst(root, date, empOids);
// Am Ende zu viele Einträge drin
return root;
}
public static List<RegelmaessigerDienstDC> GetRegelmaessigeDienste(long wOid)
{
return MapperFactory.RegelmaessigerDienstDC_RegelmaessigerDienst.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive<RegelmaessigerDienst>())
.Where(x => x.WohnheimOid == wOid).ToList();
}
public static List<AbsenceTimeDC> GetAbsenceTimeVacationByWohnheim(long wohnId, int year, int month)
{
var date = new DateTime(year, month, 1);
var date2 = date.AddMonths(1).AddTicks(-1);
var wh = DAOFactory.GenericDAO.GetByID<Wohnheim>(wohnId);
var emps = wh.Employee2WohnheimList.Select(x => x.Employee.Oid);
var allAbsences = DAOFactory.GenericDAO.GetAllActive<AbsenceTime>().Where(x =>
x.EmployeeOid.HasValue);
var res = allAbsences.Where(x => emps.Contains(x.EmployeeOid.Value) && x.Start <= date2 && (!x.End.HasValue || x.End.Value >= date));
return MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(res);
}
public static List<OvertimeDC> GetOverTimesByWohnheim(long wohnId, int year, int month)
{
var date = new DateTime(year, month, 1);
var date2 = date.AddMonths(1).AddTicks(-1);
var wh = DAOFactory.GenericDAO.GetByID<Wohnheim>(wohnId);
var emps = wh.Employee2WohnheimList.Select(x => x.Employee.Oid);
var allOvertimes = DAOFactory.GenericDAO.GetAllActive<Overtime>().Where(x => x.EmployeeOid.HasValue);
List<Overtime> ots = allOvertimes.Where(x => emps.Contains(x.EmployeeOid.Value) && x.Date >= date && x.Date <= date2).ToList();
return MapperFactory.OvertimeDC_Overtime.MapToNewDCs(ots);
}
public static List<DienstInfoDC> GetAllDienste(long? whOid)
{
List<DienstInfo> list = new List<DienstInfo>();
if (whOid == null)
{
list = DAOFactory.GenericDAO.GetAllActive<DienstInfo>().ToList();
var withoutWH = new List<DienstInfo>();
foreach (var d in list)
{
if (d.Wohnheim == null)
withoutWH.Add(d);
}
list.RemoveRange(withoutWH);
list = list.OrderBy(l => l.Wohnheim).ThenBy(d => d.DienstName).ToList();
list.AddRange(withoutWH.OrderBy(w => w.DienstName));
}
else
list = DAOFactory.SearchDAO.FindDiensteForWohnheim(whOid).ToList();
var dcs = MapperFactory.DienstInfoDC_DienstInfo.MapToNewDCs(list);
return dcs;
}
public static void InsertNewDienst(List<DienstInfoDC> dienst)
{
var temp = MapperFactory.DienstInfoDC_DienstInfo.MapToNewEntities(dienst);
DAOFactory.GenericDAO.Insert(temp);
}
public static void DeactivateDienst(Dictionary<long, long> pOid2Version)
{
ServiceLogic.SetActivationType<DienstInfo>(pOid2Version, ActivationTypeId.Deleted);
// Alle Diensteinträge und Vertretungen mit diesem Dienst suchen
var diensteintraege = DAOFactory.GenericDAO.GetAllActive<DienstEintrag>();
var dienstvertretungen = DAOFactory.GenericDAO.GetAllActive<Dienstvertretung>();
foreach (var e in diensteintraege)
if (pOid2Version.ContainsKey(e.DienstOid))
DAOFactory.GenericDAO.Delete(e);
foreach (var v in dienstvertretungen)
if (pOid2Version.ContainsKey(v.DienstOid))
DAOFactory.GenericDAO.Delete(v);
}
public static void UpdateDienst(List<DienstInfoDC> dienste)
{
var temp = DAOFactory.GenericDAO.LoadByIDs<DienstInfo>(dienste.Select(sc => sc.Oid.Value));
MapperFactory.DienstInfoDC_DienstInfo.MergeWithEntitys(dienste, temp);
DAOFactory.GenericDAO.Update(temp);
}
public static List<DienstEintragDC> GetAllDienstEintraegeAsList(long wOid, int year, int month)
{
var res = new List<DienstEintragDC>();
var dienstEintraege = DAOFactory.SearchDAO.GetAllDienstEintraege(wOid, new DateTime(year, month, 1), new DateTime(year, month, 1).AddMonths(1).AddMinutes(-1));
var dienstEintraegeDC = MapperFactory.DienstEintragDC_DienstEintrag.MapToNewDCs(dienstEintraege);
List<DienstEintragDC> dopplungen = new List<DienstEintragDC>();
List<DienstEintragDC> schonGehabt = new List<DienstEintragDC>();
foreach (var item in dienstEintraegeDC)
{
var t = schonGehabt.Where(i => i.EmployeeOid == item.EmployeeOid && i.Zeile == item.Zeile && i.Datum == item.Datum).ToList();
if (t.Count > 0)
{
foreach (var i in t)
{
if (dopplungen.FirstOrDefault(d => d.Oid == i.Oid) == null)
dopplungen.Add(i);
}
}
schonGehabt.Add(item);
}
foreach (var d in dopplungen)
{
for (int i = dienstEintraegeDC.Count - 1; i >= 0; i--)
{
var eintrag = dienstEintraegeDC[i];
if (d.EmployeeOid == eintrag.EmployeeOid && d.Datum == eintrag.Datum && d.Zeile == eintrag.Zeile && dienstEintraegeDC.Where(e => d.EmployeeOid == e.EmployeeOid && d.Datum == e.Datum && d.Zeile == e.Zeile).ToList().Count > 1)
{
dienstEintraegeDC.RemoveAt(i);
//DeleteDienstEintrag(eintrag.EmployeeOid, eintrag.WohnheimOid, eintrag.Zeile, eintrag.Datum);
}
}
}
//
res.AddRange(dienstEintraegeDC);
return res;
}
public static List<DienstvertretungDC> GetAllDienstvertretungenAsList(long wOid, int year, int month)
{
var res = new List<DienstvertretungDC>();
var wh = MapperFactory.WohnheimDC_Wohnheim.MapToNewDC(DAOFactory.GenericDAO.GetByID<Wohnheim>(wOid));
var dienstvertretungen = DAOFactory.GenericDAO.GetAllActive<Dienstvertretung>().Where(x =>
x.WohnheimOid == wOid &&
x.Datum.Month == month &&
x.Datum.Year == year)
.ToList();
var dienstvertretungenDC = MapperFactory.DienstvertretungDC_Dienstvertretung.MapToNewDCs(dienstvertretungen);
//
List<DienstvertretungDC> dopplungen = new List<DienstvertretungDC>();
List<DienstvertretungDC> schonGehabt = new List<DienstvertretungDC>();
foreach (var item in dienstvertretungenDC)
{
var t = schonGehabt.Where(i => i.EmployeeOid == item.EmployeeOid && i.Zeile == item.Zeile && i.Datum == item.Datum).ToList();
if (t.Count > 0)
{
foreach (var i in t)
{
if (dopplungen.FirstOrDefault(d => d.Oid == i.Oid) == null)
dopplungen.Add(i);
}
}
schonGehabt.Add(item);
}
foreach (var d in dopplungen)
{
for (int i = dienstvertretungenDC.Count - 1; i >= 0; i--)
{
var eintrag = dienstvertretungenDC[i];
if (d.EmployeeOid == eintrag.EmployeeOid && d.Datum == eintrag.Datum && d.Zeile == eintrag.Zeile && dienstvertretungenDC.Where(e => d.EmployeeOid == e.EmployeeOid && d.Datum == e.Datum && d.Zeile == e.Zeile).ToList().Count > 1)
{
dienstvertretungenDC.RemoveAt(i);
DeleteDienstEintrag(eintrag.EmployeeOid, eintrag.WohnheimOid, eintrag.Zeile, eintrag.Datum);
}
}
}
//
res.AddRange(dienstvertretungenDC);
return res;
}
public static List<DienstBlockDC> GetDienstEintraege(long wOid, int year, int month)
{
var res = new List<DienstBlockDC>();
var date = new DateTime(year, month, 1);
var date2 = date.AddMonths(1).AddTicks(-1);
var dienstEintraegeDC = GetAllDienstEintraegeAsList(wOid, year, month);
var wh = DAOFactory.GenericDAO.GetByID<Wohnheim>(wOid);
var whDC = MapperFactory.CompactWohnheimDC_Wohnheim.MapToNewDC(wh);
var emps = wh.Employee2WohnheimList.Select(x => x.Employee);
var empsDC = MapperFactory.EmployeeDC_Employee.MapToNewDCs(emps).Distinct();
foreach (var emp in empsDC)
{ //BP
var contracts = emp.Contracts.Where(x => (!x.EntryDate.HasValue || x.EntryDate.Value <= date2) &&
(!x.ContractEndDate.HasValue || x.ContractEndDate.Value >= date))
.OrderBy(x => x.EntryDate)
.ToList();
if (!contracts.Any())
continue;
var zeile = new DienstBlockDC
{
Employee = emp,
Contracts = contracts,
Wohnheim = whDC,
DienstDictArray = new Dictionary<int, long>[20]
};
for (int i = 0; i < zeile.DienstDictArray.Length; i++)
{
var empDienste = dienstEintraegeDC
.Where(x => x.EmployeeOid == emp.EmployeeOid && x.Zeile == i).ToList();
var empDiensteFinal = new List<DienstEintragDC>();
foreach (var item in empDienste)
{
if (!empDiensteFinal.Any(d => d.Datum == item.Datum && d.Zeile == item.Zeile))
empDiensteFinal.Add(item);
else
Console.WriteLine("Key existiert schon");
}
zeile.DienstDictArray[i] = empDiensteFinal
.ToDictionary(x => x.Datum.Day, x => x.DienstOid);
}
res.Add(zeile);
}
//Frühere Schichten entfernter Mitarbeiter anzeigen lassen
List<long?> oids = new List<long?>();
foreach (var emp in empsDC)
oids.Add(emp.EmployeeOid);
foreach (var eintrag in dienstEintraegeDC)
{
if (!oids.Contains(eintrag.EmployeeOid))
{
var emp = MapperFactory.EmployeeDC_Employee.MapToNewDC(DAOFactory.GenericDAO.GetByID<Employee>(eintrag.EmployeeOid));
var contracts = emp.Contracts.Where(x => (!x.EntryDate.HasValue || x.EntryDate.Value <= date2) &&
(!x.ContractEndDate.HasValue || x.ContractEndDate.Value >= date))
.OrderBy(x => x.EntryDate)
.ToList();
var zeile = new DienstBlockDC
{
Employee = emp,
Contracts = contracts,
Wohnheim = whDC,
DienstDictArray = new Dictionary<int, long>[20]
};
for (int i = 0; i < zeile.DienstDictArray.Length; i++)
{
var empDienste = dienstEintraegeDC
.Where(x => x.EmployeeOid == emp.EmployeeOid && x.Zeile == i);
zeile.DienstDictArray[i] = empDienste
.ToDictionary(x => x.Datum.Day, x => x.DienstOid);
}
oids.Add(eintrag.EmployeeOid);
res.Add(zeile);
}
}
return res;
}
public static List<DienstBlockDC> GetDienstvertretungen(long wOid, int year, int month)
{ //BP
var res = new List<DienstBlockDC>();
var wh = DAOFactory.GenericDAO.GetByID<Wohnheim>(wOid);
var whDC = MapperFactory.CompactWohnheimDC_Wohnheim.MapToNewDC(wh);
var date = new DateTime(year, month, 1);
var date2 = date.AddMonths(1).AddTicks(-1);
var dienstvertretung = DAOFactory.GenericDAO.GetAllActive<Dienstvertretung>().Where(x =>
x.WohnheimOid == wOid &&
x.Datum.Month == month &&
x.Datum.Year == year)
.ToList();
// WENN ES KRACHT DIESE FOR-SCHLEIFE AUSKOMMENTIEREN
// Mitarbeitende, die sowieso im Wohnheim arbeiten, sollen nicht noch zusätzlich als Vertretung dargestellt werden
for (int i = dienstvertretung.Count - 1; i >= 0; i--)
{
if (wh.Employee2WohnheimList.Any(e => e.Employee.Oid == dienstvertretung[i].EmployeeOid))
{
dienstvertretung.RemoveAt(i);
}
}
var dienstvertretungenDC = MapperFactory.DienstvertretungDC_Dienstvertretung.MapToNewDCs(dienstvertretung);
//var vertretungenAndrianarivo = dienstvertretungenDC.Where(dv => dv.EmployeeOid == 36).ToList(); // debug
List<long> empOids = new List<long>();
foreach (var vertretung in dienstvertretungenDC)
{
if (vertretung.WohnheimOid == wOid)
{
if (empOids.Count == 0)
empOids.Add(vertretung.EmployeeOid);
else
{
if (!empOids.Contains(vertretung.EmployeeOid))
empOids.Add(vertretung.EmployeeOid);
}
}
}
List<EmployeeDC> empsDC = new List<EmployeeDC>();
foreach (var oid in empOids)
{
empsDC.Add(MapperFactory.EmployeeDC_Employee.MapToNewDC(DAOFactory.GenericDAO.GetByID<Employee>(oid)));
}
//var emps = wh.Employee2WohnheimList.Select(x => x.Employee);
//var empsDC = MapperFactory.EmployeeDC_Employee.MapToNewDCs(emps).Distinct();
foreach (var emp in empsDC)
{
var contracts = emp.Contracts.Where(x => (!x.EntryDate.HasValue || x.EntryDate.Value <= date2) &&
(!x.ContractEndDate.HasValue || x.ContractEndDate.Value >= date))
.OrderBy(x => x.EntryDate)
.ToList();
if (!contracts.Any())
continue;
var zeile = new DienstBlockDC
{
Employee = emp,
Contracts = contracts,
Wohnheim = whDC,
DienstDictArray = new Dictionary<int, long>[20]
};
for (int i = 0; i < zeile.DienstDictArray.Length; i++)
{
var empDienste = dienstvertretungenDC
.Where(x => x.EmployeeOid == emp.EmployeeOid && x.Zeile == i).ToList();
// Doppelte rausnehmen, die sollte es technisch eigentlich gar nicht geben
var doppelteEintraege = empDienste
.GroupBy(e => new { e.EmployeeOid, e.Zeile, e.Datum })
.Where(g => g.Count() > 1) // Nur welche, die es mehr als einmal gibt
.SelectMany(g => g.Skip(1)) // Lässt das erste Element weg, damit beim Löschen der Doppelten einer übrig bleibt
.ToList();
//if (emp.EmployeeOid == 36)
//{
//}
if (doppelteEintraege != null && doppelteEintraege.Count > 0)
{
for (int x = empDienste.Count - 1; x > 0; x--)
{
var dienst = empDienste[x];
if (doppelteEintraege.Any(d => d.Oid == dienst.Oid))
empDienste.RemoveAt(x);
}
}
zeile.DienstDictArray[i] = empDienste
.ToDictionary(x => x.Datum.Day, x => x.DienstOid);
}
res.Add(zeile);
}
return res;
}
public static void InsertNewDienstEintrag(DienstEintragDC dienstEintrag)
{
DAOFactory.GenericDAO.Insert(MapperFactory.DienstEintragDC_DienstEintrag.MapToNewEntity(dienstEintrag));
}
public static bool InsertNewDienstEintrag2(DienstEintragDC dienstEintrag, List<DienstEintragDC> alleDiensteintraege, List<DienstvertretungDC> alleDienstvertretungen,
int day, DateTime pflichtStart, DateTime pflichtEnde)
{
DAOFactory.GenericDAO.Insert(MapperFactory.DienstEintragDC_DienstEintrag.MapToNewEntity(dienstEintrag));
alleDiensteintraege.Add(dienstEintrag);
return RefreshStatusForDay(alleDiensteintraege, alleDienstvertretungen, day, pflichtStart, pflichtEnde);
}
public static void InsertNewDienstEintraege(List<DienstEintragDC> dienstEintraege)
{
DAOFactory.GenericDAO.Insert(MapperFactory.DienstEintragDC_DienstEintrag.MapToNewEntities(dienstEintraege));
}
public static void InsertNewDienstvertretung(DienstvertretungDC dienstvertretung)
{
DAOFactory.GenericDAO.Insert(MapperFactory.DienstvertretungDC_Dienstvertretung.MapToNewEntity(dienstvertretung));
}
public static bool InsertNewDienstvertretung2(DienstvertretungDC dienstvertretung, List<DienstEintragDC> alleDiensteintraege, List<DienstvertretungDC> alleDienstvertretungen,
int day, DateTime pflichtStart, DateTime pflichtEnde)
{
DAOFactory.GenericDAO.Insert(MapperFactory.DienstvertretungDC_Dienstvertretung.MapToNewEntity(dienstvertretung));
alleDienstvertretungen.Add(dienstvertretung);
return RefreshStatusForDay(alleDiensteintraege, alleDienstvertretungen, day, pflichtStart, pflichtEnde);
}
public static void DeleteDienstEintrag(long empId, long wohnId, int zeile, DateTime date)
{
var toDel = DAOFactory.GenericDAO.GetAll<DienstEintrag>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date &&
x.IsActive == ActivationTypeId.Active);
//if (toDel != null)
// DAOFactory.GenericDAO.Delete(toDel);
if (toDel != null)
{
DAOFactory.GenericDAO.Deactivate(toDel);
}
}
public static bool DeleteDienstEintrag2(long empId, long wohnId, int zeile, DateTime date, DienstEintragDC dienstEintrag, List<DienstEintragDC> alleDiensteintraege,
List<DienstvertretungDC> alleDienstvertretungen, int day, DateTime pflichtStart, DateTime pflichtEnde)
{
var toDel = DAOFactory.GenericDAO.GetAll<DienstEintrag>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date &&
x.IsActive == ActivationTypeId.Active);
if (toDel != null)
DAOFactory.GenericDAO.Delete(toDel);
var eintrag = alleDiensteintraege.FirstOrDefault(e => e.EmployeeOid == empId && e.WohnheimOid == wohnId && e.Zeile == zeile && e.Datum == date);
if (eintrag != null)
{
int? index = null;
for (int i = 0; i < alleDiensteintraege.Count; i++)
{
var e = alleDiensteintraege[i];
if (e.EmployeeOid == eintrag.EmployeeOid && e.WohnheimOid == eintrag.WohnheimOid && e.Zeile == eintrag.Zeile && e.Datum == eintrag.Datum)
index = i;
}
if (index != null)
alleDiensteintraege.RemoveAt(index.Value);
}
return RefreshStatusForDay(alleDiensteintraege, alleDienstvertretungen, day, pflichtStart, pflichtEnde);
}
public static void DeleteDienstvertretung(long empId, long wohnId, int zeile, DateTime date)
{
var toDel = DAOFactory.GenericDAO.GetAll<Dienstvertretung>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date);
if (toDel != null)
DAOFactory.GenericDAO.Delete(toDel);
}
public static bool DeleteDienstvertretung2(long empId, long wohnId, int zeile, DateTime date, DienstvertretungDC dienstvertretung, List<DienstEintragDC> alleDiensteintraege,
List<DienstvertretungDC> alleDienstvertretungen, int day, DateTime pflichtStart, DateTime pflichtEnde)
{
var toDel = DAOFactory.GenericDAO.GetAll<Dienstvertretung>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date);
if (toDel != null)
DAOFactory.GenericDAO.Delete(toDel);
var vertretung = alleDienstvertretungen.FirstOrDefault(e => e.EmployeeOid == empId && e.WohnheimOid == wohnId && e.Zeile == zeile && e.Datum == date);
if (vertretung != null)
{
int? index = null;
for (int i = 0; i < alleDienstvertretungen.Count; i++)
{
var e = alleDienstvertretungen[i];
if (e.EmployeeOid == vertretung.EmployeeOid && e.WohnheimOid == vertretung.WohnheimOid && e.Zeile == vertretung.Zeile && e.Datum == vertretung.Datum)
index = i;
}
if (index != null)
alleDienstvertretungen.RemoveAt(index.Value);
}
return RefreshStatusForDay(alleDiensteintraege, alleDienstvertretungen, day, pflichtStart, pflichtEnde);
}
public static void DeleteCertainDienstEintragOutOfTable(long dienstEintragOid)
{
var toDelete = DAOFactory.GenericDAO.GetAll<DienstEintrag>();
for (int i = toDelete.Count - 1; i >= 0; i--)
{
if (toDelete[i].DienstOid == dienstEintragOid)
DAOFactory.GenericDAO.Delete(toDelete[i]);
}
}
public static void RemoveAllDiensteForOneMonth(CompactWohnheimDC wh, DateTime month, List<RegelmaessigerDienstDC> rd)
{
if (rd.Count > 0)
{
List<RegelmaessigerDienst> entities = new List<RegelmaessigerDienst>();
foreach (var dienst in rd)
{
entities.Add(DAOFactory.GenericDAO.GetByID<RegelmaessigerDienst>((long)dienst.Oid));
}
DAOFactory.GenericDAO.Delete(entities);
}
var alleDienste = DAOFactory.GenericDAO.GetAll<DienstEintrag>();
var alleVertretungen = DAOFactory.GenericDAO.GetAll<Dienstvertretung>();
foreach (var dienst in alleDienste)
{
if (dienst.Datum.Month == month.Month && dienst.WohnheimOid == wh.WohnheimOid)
DAOFactory.GenericDAO.Delete(dienst);
}
foreach (var vertretung in alleVertretungen)
{
if (vertretung.Datum.Month == month.Month && vertretung.WohnheimOid == wh.WohnheimOid)
DAOFactory.GenericDAO.Delete(vertretung);
}
}
public static void RemoveAllDiensteForOneYear(CompactWohnheimDC wh, DateTime year, List<RegelmaessigerDienstDC> rd)
{
if (rd.Count > 0)
{
List<RegelmaessigerDienst> entities = new List<RegelmaessigerDienst>();
foreach (var dienst in rd)
{
entities.Add(DAOFactory.GenericDAO.GetByID<RegelmaessigerDienst>((long)dienst.Oid));
}
DAOFactory.GenericDAO.Delete(entities);
}
var alleDienste = DAOFactory.GenericDAO.GetAll<DienstEintrag>();
var alleVertretungen = DAOFactory.GenericDAO.GetAll<Dienstvertretung>();
foreach (var dienst in alleDienste)
{
if (dienst.Datum.Year == year.Year && dienst.WohnheimOid == wh.WohnheimOid)
DAOFactory.GenericDAO.Delete(dienst);
}
foreach (var vertretung in alleVertretungen)
{
if (vertretung.Datum.Year == year.Year && vertretung.WohnheimOid == wh.WohnheimOid)
DAOFactory.GenericDAO.Delete(vertretung);
}
}
public static string GetBemerkungForDienstEintrag(long empId, long wohnId, int zeile, DateTime date)
{
var res = DAOFactory.GenericDAO.GetAll<DienstEintrag>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date);
if (res != null)
return res.Notice;
else
return "";
}
public static DienstEintragDC GetDienstEintrag(long empId, long wohnId, int zeile, DateTime date)
{
var eintrag = DAOFactory.GenericDAO.GetAll<DienstEintrag>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date);
return (eintrag != null) ? MapperFactory.DienstEintragDC_DienstEintrag.MapToNewDC(eintrag) : null;
}
public static DienstvertretungDC GetDienstvertretung(long empId, long wohnId, int zeile, DateTime date)
{
var eintrag = DAOFactory.GenericDAO.GetAll<Dienstvertretung>()
.FirstOrDefault(x =>
x.EmployeeOid == empId &&
x.WohnheimOid == wohnId &&
x.Zeile == zeile &&
x.Datum == date);
return (eintrag != null) ? MapperFactory.DienstvertretungDC_Dienstvertretung.MapToNewDC(eintrag) : null;
}
public static void UpdateDienstEintrag(DienstEintragDC dienstEintrag)
{
var entity = MapperFactory.DienstEintragDC_DienstEintrag.MapToNewEntity(dienstEintrag);
DAOFactory.GenericDAO.Update(entity);
}
public static string GetColorForStatus(bool status)
{
return (status) ? "#FF228B22" : "#FFCD5C5C";
}
public static string GetColorForForeground()
{
return "#FF6495ED";
}
public static List<DienstplanerMonthlySummaryDC> BerechneSollSaldoUndIst(DienstplanerRootDC root, DateTime date, List<long> empOids)
{
VacationService vs = PluginLoader.FindClass<VacationService>();
var konto = MitarbeiterstundenkontoRONeu.Create(null, null, date, date.AddMonths(1), empOids);
DienstplanungsManager manager = PluginLoader.FindClass<DienstplanungsManager>();
var berechnung = PluginLoader.FindClass<MitarbeiterstundenkontoBerechnungNeu>();
berechnung.CreateReport(konto);
List<DienstplanerMonthlySummaryDC> monatsZusammenfassung = new List<DienstplanerMonthlySummaryDC>();
root.StundenBeiAbwesenheit = new Dictionary<long?, decimal>();
// Claude: Lookup-Dictionary einmalig aufbauen statt pro Eintrag die Dienstliste zu durchsuchen
var dienstProOid = DienstInfoDC.BuildDienstProOidDictionary(root.AlleDienste);
foreach (var item in konto.EmployeeDetailList)
{
root.StundenBeiAbwesenheit.Add(item.Employee.Oid, item.SollProTag);
var employee = MapperFactory.EmployeeDC_Employee.MapToNewDC(item.Employee);
DienstplanerMonthlySummaryDC dc = new DienstplanerMonthlySummaryDC
{
Employee = employee,
//Soll = item.StundenSollOhneUrlaubKrankheit,
Soll = item.StundenSollMax,
ZeitkontoLetzterMonat = item.UeberstundenVormonat,
ZeitkontoAktualisiert = item.Ueberstunden,
TageUrlaub = 0,
TageKrank = 0
};
var eintraegeFuerMitarbeiterMonat = root.AlleDienstEintraege.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var vertretungenFuerMitarbeiterMonat = root.AlleDienstvertretungen.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var urlaubKrankheitMonat = root.AbsenceTimes.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var overTimesMonat = root.OverTimes.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
decimal stunden = 0;
//decimal abzug = 0;
if (eintraegeFuerMitarbeiterMonat.Count > 0)
{
foreach (var eintrag in eintraegeFuerMitarbeiterMonat)
{
// Claude: Pause des Dienstes von der Dauer abziehen
stunden += Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(eintrag.DauerInStunden, eintrag.DienstOid, dienstProOid));
}
}
if (vertretungenFuerMitarbeiterMonat.Count > 0)
{
foreach (var vertretung in vertretungenFuerMitarbeiterMonat)
stunden += Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(vertretung.DauerInStunden, vertretung.DienstOid, dienstProOid)); // Claude: Pause abziehen
}
if (overTimesMonat.Count > 0)
{
foreach (var ot in overTimesMonat)
stunden += ot.Betrag;
}
if (urlaubKrankheitMonat.Count > 0)
{
decimal dauer = 0;
var vorherigeWeeklyDays = 0;
var vorherigeKW = 0;
decimal tageInEinerWoche = 0; // Tage für die Ist- und Sollstunden
int wochentageVergangen = 0; // Vergangene Wochentage
decimal abzuziehendeTage = 0m;
// Um Kalenderwoche zu bekommen
CultureInfo cultureInfo = new CultureInfo("de-DE");
Calendar calendar = cultureInfo.Calendar;
CalendarWeekRule calenderWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
DayOfWeek firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
for (int i = 0; i < urlaubKrankheitMonat.Count; i++)
{
var abs = urlaubKrankheitMonat[i];
var contract = GetContract(employee.Contracts, abs.Start.Value);
////////////////////////////////////////////////////////////////////////////////////////////
if (contract != null)
{
var weeklyDays = contract.WeeklyDays;
vorherigeWeeklyDays = vorherigeWeeklyDays == 0 ? weeklyDays : vorherigeWeeklyDays;
bool skipAbsenceTime = false;
//if (berechnung.IstAnrechenbareAbsenceTime(DAOFactory.GenericDAO.GetByID<AbsenceTime>(abs.AbsenceTimeOid.Value)))
// skipAbsenceTime = true;
// Falls der Vertrag sich NICHT innerhalb einer Woche ändert
if (weeklyDays == vorherigeWeeklyDays)
{
var wochentag = abs.Start.Value.DayOfWeek;
if (!abs.End.HasValue)
abs.End = new DateTime(date.Year, 12, 31, 23, 59, 59);
if (wochentag == DayOfWeek.Monday || vorherigeKW != calendar.GetWeekOfYear(abs.Start.Value.Date, calenderWeekRule, firstDayOfWeek))
{
tageInEinerWoche = 0;
wochentageVergangen = 0;
abzuziehendeTage = 0;
}
if (wochentageVergangen >= weeklyDays || tageInEinerWoche >= weeklyDays)
{
// Hier ausprogrammieren, dass die absTime dann übersprungen wird
skipAbsenceTime = true;
}
else if (wochentageVergangen + (abs.End.Value - abs.Start.Value).TotalDays + 1 >= weeklyDays)
{
// Hier das Ende der absTime dann so setzen, dass weeklyDays voll werden. HALBE TAGE NICHT VERGESSEN
var diff = weeklyDays - wochentageVergangen;
}
}
vorherigeWeeklyDays = weeklyDays;
/////////////////////////////////////////////////////////////////////////////////////////
// Wenn die Abwesenheit über den Monat hinausgeht, Start und ende Ende auf Start und Ende des Monats setzen
if (abs.Start.Value.Month != date.Month)
abs.Start = new DateTime(date.Year, date.Month, 1);
if (abs.End != null)
{
if (abs.End.Value.Month != date.Month)
abs.End = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
}
else
abs.End = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
if (!skipAbsenceTime)
{
decimal dauerAbwesenheit = vs.BerechneAnzahlUrlaubstageMitWeeklyDays(abs, date.Year, weeklyDays);
//var dauerAbwesenheit = vs.BerechneAnzahlUrlaubstage(null, abs, date.Year);
if (abs.Reason.Description.ToLower().Contains("urlaub"))
dc.TageUrlaub += dauerAbwesenheit; //BP
else if (abs.Reason.Description.ToLower().Contains("krank"))
dc.TageKrank += dauerAbwesenheit; //BP
//dauer += dauerAbwesenheit;
decimal wochenendAbzug = 0;
if (!root.EnableAbwesenheitenAnWochenenden)
wochenendAbzug = manager.ZieheWochenendenAb(abs);
dauer += dauerAbwesenheit - wochenendAbzug;
tageInEinerWoche += dauerAbwesenheit;
wochentageVergangen += Convert.ToInt32(Math.Ceiling((abs.End.Value - abs.Start.Value).TotalDays) + 1);
//Dienste an einem ganzen Abwesenheitstag von den Stunden abziehen
foreach (var e in eintraegeFuerMitarbeiterMonat)
{
if (abs.AbsenceSpan.ContainsDate(e.Datum.Date))
{
if (dauerAbwesenheit > 0.5m)
stunden -= Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(e.DauerInStunden, e.DienstOid, dienstProOid)); // Claude: gleicher Pausenabzug wie beim Aufaddieren
}
}
foreach (var v in vertretungenFuerMitarbeiterMonat)
{
if (abs.AbsenceSpan.ContainsDate(v.Datum.Date))
{
if (dauerAbwesenheit > 0.5m)
stunden -= Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(v.DauerInStunden, v.DienstOid, dienstProOid)); // Claude: gleicher Pausenabzug wie beim Aufaddieren
}
}
}
vorherigeKW = calendar.GetWeekOfYear(abs.Start.Value.Date, calenderWeekRule, firstDayOfWeek);
if (tageInEinerWoche > weeklyDays && vorherigeKW == calendar.GetWeekOfYear(abs.End.Value.Date, calenderWeekRule, firstDayOfWeek))
abzuziehendeTage += tageInEinerWoche - weeklyDays;
}
}
stunden += dauer * item.SollProTag - abzuziehendeTage * item.SollProTag;
}
dc.Ist = stunden;
dc.Saldo = dc.Ist - dc.Soll;
monatsZusammenfassung.Add(dc);
}
return monatsZusammenfassung;
}
public virtual decimal ZieheWochenendenAb(AbsenceTimeDC abs)
{
decimal wochenendAbzug = 0;
var start = abs.Start.Value;
var end = abs.End.Value;
while (start <= end)
{
if (start.DayOfWeek == DayOfWeek.Saturday || start.DayOfWeek == DayOfWeek.Sunday)
wochenendAbzug++;
start = start.AddDays(1);
}
return wochenendAbzug;
}
public static DienstplanerMonthlySummaryDC BerechneSollSaldoUndIstFuerEinzelnenMitarbeiter(DateTime date, long empOid, List<DienstEintragDC> dienstEintraege, List<DienstvertretungDC> dienstvertretungen,
List<AbsenceTimeDC> absenceTimes, List<OvertimeDC> overtimes, out long stundenBeiAbwesenheitKey, out decimal stundenBeiAbwesenheitValue)
{
VacationService vs = new VacationService();
List<long> empOids = new List<long>() { empOid };
var konto = MitarbeiterstundenkontoRONeu.Create(null, null, date, date.AddMonths(1), empOids);
var berechnung = PluginLoader.FindClass<MitarbeiterstundenkontoBerechnungNeu>();
berechnung.CreateReport(konto);
DienstplanerMonthlySummaryDC dc = new DienstplanerMonthlySummaryDC();
// Claude: Nur die von diesem Mitarbeiter tatsächlich verwendeten Dienste laden (statt aller Dienste),
// um deren Pausen von der Dauer der Einträge abziehen zu können
var dienstProOid = new Dictionary<long, DienstInfoDC>();
var verwendeteDienstOids = dienstEintraege.Where(x => x.EmployeeOid == empOid).Select(x => x.DienstOid)
.Concat(dienstvertretungen.Where(x => x.EmployeeOid == empOid).Select(x => x.DienstOid))
.Distinct();
foreach (var dienstOid in verwendeteDienstOids)
{
var dienstEntity = DAOFactory.GenericDAO.GetByID<DienstInfo>(dienstOid);
if (dienstEntity != null)
dienstProOid.Add(dienstOid, MapperFactory.DienstInfoDC_DienstInfo.MapToNewDC(dienstEntity));
}
stundenBeiAbwesenheitKey = empOid;
stundenBeiAbwesenheitValue = 0;
foreach (var item in konto.EmployeeDetailList)
{
stundenBeiAbwesenheitValue = item.SollProTag;
dc = new DienstplanerMonthlySummaryDC
{
Employee = MapperFactory.EmployeeDC_Employee.MapToNewDC(item.Employee),
Soll = item.StundenSollOhneUrlaubKrankheit,
ZeitkontoLetzterMonat = item.UeberstundenVormonat,
ZeitkontoAktualisiert = item.Ueberstunden,
TageUrlaub = 0,
TageKrank = 0
};
var eintraegeFuerMitarbeiterMonat = dienstEintraege.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var vertretungenFuerMitarbeiterMonat = dienstvertretungen.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var urlaubKrankheitMonat = absenceTimes.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
var overTimesMonat = overtimes.FindAll(x => x.EmployeeOid == dc.Employee.EmployeeOid).ToList();
decimal stunden = 0;
//decimal abzug = 0;
if (eintraegeFuerMitarbeiterMonat.Count > 0)
{
foreach (var eintrag in eintraegeFuerMitarbeiterMonat)
{
// Claude: Pause des Dienstes von der Dauer abziehen
stunden += Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(eintrag.DauerInStunden, eintrag.DienstOid, dienstProOid));
}
}
if (vertretungenFuerMitarbeiterMonat.Count > 0)
{
foreach (var vertretung in vertretungenFuerMitarbeiterMonat)
stunden += Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(vertretung.DauerInStunden, vertretung.DienstOid, dienstProOid)); // Claude: Pause abziehen
}
if (overTimesMonat.Count > 0)
{
foreach (var ot in overTimesMonat)
stunden += ot.Betrag;
}
if (urlaubKrankheitMonat.Count > 0)
{
decimal dauer = 0;
foreach (var abs in urlaubKrankheitMonat)
{
// Wenn die Abwesenheit über den Monat hinausgeht, Start und ende Ende auf Start und Ende des Monats setzen
if (abs.Start.Value.Month != date.Month)
abs.Start = new DateTime(date.Year, date.Month, 1);
if (abs.End != null)
{
if (abs.End.Value.Month != date.Month)
abs.End = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
}
else
abs.End = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
var dauerAbwesenheit = vs.BerechneAnzahlUrlaubstage(null, abs, date.Year, item.ArbeitstageProWoche);
if (abs.Reason.Description.ToLower().Contains("urlaub"))
dc.TageUrlaub += dauerAbwesenheit * item.SollProTag;
else if (abs.Reason.Description.ToLower().Contains("krank"))
dc.TageKrank += dauerAbwesenheit * item.SollProTag;
dauer += dauerAbwesenheit;
//Dienste an einem ganzen Abwesenheitstag von den Stunden abziehen
foreach (var e in eintraegeFuerMitarbeiterMonat)
{
if (abs.AbsenceSpan.ContainsDate(e.Datum.Date))
{
if (dauerAbwesenheit > 0.5m)
stunden -= Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(e.DauerInStunden, e.DienstOid, dienstProOid)); // Claude: gleicher Pausenabzug wie beim Aufaddieren
}
}
foreach (var v in vertretungenFuerMitarbeiterMonat)
{
if (abs.AbsenceSpan.ContainsDate(v.Datum.Date))
{
if (dauerAbwesenheit > 0.5m)
stunden -= Convert.ToDecimal(DienstInfoDC.DauerAbzueglichPause(v.DauerInStunden, v.DienstOid, dienstProOid)); // Claude: gleicher Pausenabzug wie beim Aufaddieren
}
}
}
stunden += dauer * item.SollProTag;
}
dc.Ist = stunden;
dc.Saldo = dc.Ist - dc.Soll;
}
return dc;
}
public static void DeleteRegelmaessigeDiensteOfRemovedEmployee(List<CompactEmployeeDC> employee, long wOid)
{
if (employee.Count > 0)
{
foreach (var emp in employee)
{
var regelmaessigenDienste = GetRegelmaessigeDienste(wOid).Where(d => d.EmployeeOid == emp.EmployeeOid);
List<RegelmaessigerDienst> entities = new List<RegelmaessigerDienst>();
foreach (var dienst in regelmaessigenDienste)
entities.Add(DAOFactory.GenericDAO.GetByID<RegelmaessigerDienst>((long)dienst.Oid));
DAOFactory.GenericDAO.Delete(entities);
}
}
}
public static List<string> SetSortierMethoden()
{
List<string> auswahl = new List<string>();
foreach (var e in Enum.GetValues(typeof(Sortierungsarten)))
{
auswahl.Add(e.ToString());
}
return auswahl;
}
public static List<CompactEmployeeDC> GetCompactEmployeesForTeam(long teamOid)
{
var team = DAOFactory.GenericDAO.GetByID<Team>(teamOid);
return MapperFactory.CompactEmployeeDC_Employee.MapToNewDCs(team.MemberList); ;
}
public static List<DienstBlockDC> DienstBloeckeNeuSortieren(List<DienstBlockDC> bloecke, string auswahl, bool aufsteigend)
{
switch (auswahl)
{
case "Alphabetisch": //Sortierungsarten.Alphabetisch (BeWoEntityEnumns)
if (aufsteigend)
bloecke = bloecke.OrderBy(d => d.Employee.LastName).ToList();
else
bloecke = bloecke.OrderByDescending(d => d.Employee.LastName).ToList();
break;
case "Dienstanzahl": //Sortierungsarten.Dienstanzahl (BeWoEntityEnumns)
bloecke = NachMengeDerDiensteSortieren(bloecke, aufsteigend);
break;
}
return bloecke;
}
private static List<DienstBlockDC> NachMengeDerDiensteSortieren(List<DienstBlockDC> bloecke, bool aufsteigend)
{
Dictionary<long?, int> anzahlDiensteProMitarbeiter = new Dictionary<long?, int>();
foreach (var block in bloecke)
{
foreach (var dict in block.DienstDictArray)
{
if (!anzahlDiensteProMitarbeiter.ContainsKey(block.Employee.EmployeeOid))
anzahlDiensteProMitarbeiter.Add(block.Employee.EmployeeOid, dict.Count);
else
anzahlDiensteProMitarbeiter[block.Employee.EmployeeOid] += dict.Count;
}
}
if (!aufsteigend)
{
List<DienstBlockDC> bloeckeNeuSortiert = new List<DienstBlockDC>();
int max = 0;
long? nextEmployee = null;
while (bloecke.Count != bloeckeNeuSortiert.Count)
{
foreach (var anz in anzahlDiensteProMitarbeiter)
{
if (anz.Value > max)
{
nextEmployee = anz.Key;
max = anz.Value;
}
else if (anz.Value == 0)
{
nextEmployee = anz.Key;
}
}
anzahlDiensteProMitarbeiter.Remove(nextEmployee);
max = 0;
bloeckeNeuSortiert.AddRange(bloecke.Where(b => b.Employee.EmployeeOid == nextEmployee));
}
return bloeckeNeuSortiert;
}
else
{
List<DienstBlockDC> bloeckeNeuSortiert = new List<DienstBlockDC>();
int min = 99999;
long? nextEmployee = null;
while (bloecke.Count != bloeckeNeuSortiert.Count)
{
foreach (var anz in anzahlDiensteProMitarbeiter)
{
if (anz.Value < min)
{
nextEmployee = anz.Key;
min = anz.Value;
}
}
anzahlDiensteProMitarbeiter.Remove(nextEmployee);
min = 99999;
bloeckeNeuSortiert.AddRange(bloecke.Where(b => b.Employee.EmployeeOid == nextEmployee));
}
return bloeckeNeuSortiert;
}
}
public static List<DienstZeileDC> Init(DienstBlockDC block, List<DienstInfoDC> dienste, DateTime date, int? standardanzahlZeilen)
{
var res = new List<DienstZeileDC>();
int maxRows = 0;
for (int i = 0; i < block.DienstDictArray.Length; i++)
{
if (block.DienstDictArray[i].Count > 0)
maxRows = i;
}
if (standardanzahlZeilen == null || standardanzahlZeilen.Value == 0)
standardanzahlZeilen = 1;
for (int i = 0; i < block.DienstDictArray.Length; i++)
{
var zeileDC = block.DienstDictArray[i];
// In if eine Bedingung einfügen, dass so lange Zeilen generiert werden, bis der (zeilen-technisch) letzte Eintrag zu sehen ist
if (zeileDC.Count > 0 || i <= maxRows || standardanzahlZeilen > maxRows && i < standardanzahlZeilen) // So viele Zeilen wie standardanzahlZeilen - 1 ist (-1 weil i ja bei 0 beginnt)
{
var newDic = new Dictionary<int, DienstInfoDC>();
if (zeileDC != null)
newDic = zeileDC.ToDictionary(k => k.Key, v => dienste.Find(x => x.Oid == v.Value));
var toAdd = new DienstZeileDC(block.Employee, block.Contracts, i, date, newDic);
res.Add(toAdd);
}
}
return res;
}
public static List<DienstZeileDC> InitNachSortieren(List<DienstBlockDC> bloecke, List<DienstInfoDC> dienste, DateTime date, int? standardanzahlZeilen)
{
var res = new List<DienstZeileDC>();
if (standardanzahlZeilen == null || standardanzahlZeilen.Value == 0)
standardanzahlZeilen = 1;
foreach (var block in bloecke)
{
int maxRows = 0;
for (int i = 0; i < block.DienstDictArray.Length; i++)
{
if (block.DienstDictArray[i].Count > 0)
maxRows = i;
}
for (int i = 0; i < block.DienstDictArray.Length; i++)
{
var zeileDC = block.DienstDictArray[i];
// In if eine Bedingung einfügen, dass so lange Zeilen generiert werden, bis der (zeilen-technisch) letzte Eintrag zu sehen ist
if (zeileDC.Count > 0 || i <= maxRows || standardanzahlZeilen > maxRows && i < standardanzahlZeilen) //Nur eine Zeile
{
var newDic = new Dictionary<int, DienstInfoDC>();
if (zeileDC != null)
newDic = zeileDC.ToDictionary(k => k.Key, v => dienste.Find(x => x.Oid == v.Value));
var toAdd = new DienstZeileDC(block.Employee, block.Contracts, i, date, newDic);
res.Add(toAdd);
}
}
}
return res;
}
public static DienstZeileDC InitStatusZeile(DateTime date)
{
var days = DateTime.DaysInMonth(date.Year, date.Month);
var zeileDC = new DienstZeileDC()
{
Contracts = null,
Date = date,
DienstDict = null,
Employee = null,
StatusListe = new List<BesetzungsstatusDC>(),
Zeile = 0
};
for (int i = 1; i <= days; i++)
{
zeileDC.StatusListe.Add(new BesetzungsstatusDC()
{
DauerhaftBesetztStatus = false,
Stunden = 0,
Tag = i
});
}
return zeileDC;
}
public static List<DienstEintragDC> AddRegelmaessigeDiensteToDienstplaner(RegelmaessigerDienstDC dc, List<DienstEintragDC> alleDienstEintraege,
List<DienstvertretungDC> alleDienstvertretungen, List<AbsenceTimeDC> absenceTimes, List<FeiertagDC> feiertage, bool enableDiensteAnFeiertagen,
List<DienstZeileDC> dienstZeilenListe, DateTime pflichtStart, DateTime pflichtEnde, bool enableStatusZeile, DateTime datum)
{
DayOfWeek weekday = DayOfWeek.Monday;
bool success = false;
List<DienstEintragDC> dienstEintraegeToAdd = new List<DienstEintragDC>();
//Wochentag, an dem der Dienst immer stattfinden soll, setzen
switch (dc.Wochentag)
{
case "Montag":
weekday = DayOfWeek.Monday;
success = true;
break;
case "Dienstag":
weekday = DayOfWeek.Tuesday;
success = true;
break;
case "Mittwoch":
weekday = DayOfWeek.Wednesday;
success = true;
break;
case "Donnerstag":
weekday = DayOfWeek.Thursday;
success = true;
break;
case "Freitag":
weekday = DayOfWeek.Friday;
success = true;
break;
case "Samstag":
weekday = DayOfWeek.Saturday;
success = true;
break;
case "Sonntag":
weekday = DayOfWeek.Sunday;
success = true;
break;
}
if (success)
{
// Jeden Tag im Monat durchlaufen
for (int i = 1; i <= DateTime.DaysInMonth(datum.Year, datum.Month); i++)
{
DateTime date = new DateTime(datum.Year, datum.Month, i);
// Wenn der Wochentag des aktuellen Datums dem des regelm. Dienstes entspricht, Kriterien überprüfen
if (date.DayOfWeek == weekday)
{
bool eintragFuerDatumExistiert = false;
// Prüfen, ob für den Tag bereits ein Dienst existiert
foreach (var eintrag in alleDienstEintraege)
{
if (eintrag.Datum.Date == date.Date && eintrag.EmployeeOid == dc.EmployeeOid && eintrag.Zeile == dc.Zeile)
{
eintragFuerDatumExistiert = true;
break;
}
}
// Prüfen, ob für den Tag eine Abwesenheit existiert
foreach (var absTime in absenceTimes)
{
if (absTime.AbsenceSpan.ContainsDate(new DateTime(datum.Year, datum.Month, i)) && absTime.EmployeeOid == dc.EmployeeOid)
{
eintragFuerDatumExistiert = true;
break;
}
}
// Prüfen, ob an diesem Tag ein Feiertag ist
if (!enableDiensteAnFeiertagen)
{
foreach (var tag in feiertage)
{
if (tag.Datum.Date == date.Date)
{
eintragFuerDatumExistiert = true;
break;
}
}
}
foreach (var abwesenheit in absenceTimes.Where(a => a.EmployeeOid == dc.EmployeeOid))
{
if (abwesenheit.AbsenceSpan.ContainsDate(date))
{
eintragFuerDatumExistiert = true;
break;
}
}
// Wenn keine der vorherigen Überprüfungen ein positives Ergebnis geliefert hat, wird der regelmäßige Dienst eingesetzt
if (!eintragFuerDatumExistiert)
{
DienstEintragDC eintrag = new DienstEintragDC()
{
Datum = date,
DauerInStunden = dc.DauerInStunden,
DienstOid = dc.DienstOid,
EmployeeOid = dc.EmployeeOid,
Endzeit = dc.Endzeit,
Startzeit = dc.Startzeit,
WohnheimOid = dc.WohnheimOid,
Zeile = dc.Zeile
};
if (enableStatusZeile)
dienstZeilenListe[0].StatusListe[date.Day - 1].DauerhaftBesetztStatus = InsertNewDienstEintrag2(eintrag, alleDienstEintraege,
alleDienstvertretungen, date.Day, pflichtStart, pflichtEnde);
else
InsertNewDienstEintrag(eintrag);
dienstEintraegeToAdd.Add(eintrag);
#region auskommentiert
// Dienst in die entsprechende Zelle der Zeile einsetzen
//if (_AuswahlDienstZeileDC != null)
//{
// _AuswahlDienstZeileDC.AddDienst(i, routine_listbox_dienste.SelectedItem as DienstInfoDC);
// foreach (var item in root.DienstDCListe)
// {
// if (item.Employee.EmployeeOid == eintrag.EmployeeOid)
// {
// if (!item.DienstDictArray[eintrag.Zeile].ContainsKey(i))
// item.DienstDictArray[eintrag.Zeile].Add(i, eintrag.DienstOid);
// }
// }
//}
//else
//{
// foreach (var item in root.DienstDCListe)
// {
// if (item.Employee.EmployeeOid == eintrag.EmployeeOid)
// {
// if (!item.DienstDictArray[eintrag.Zeile].ContainsKey(i))
// item.DienstDictArray[eintrag.Zeile].Add(i, eintrag.DienstOid);
// }
// }
//}
// Status, Ist und Saldo updaten
//if (root.EnableStatuszeile)
// RefreshStatusForDay(i);
//foreach (var item in root.MonatsZusammenfassung)
//{
// if (item.Employee.EmployeeOid == dc.EmployeeOid)
// {
// item.Ist += Convert.ToDecimal(eintrag.DauerInStunden);
// item.Saldo += Convert.ToDecimal(eintrag.DauerInStunden);
// }
//}
#endregion
}
}
}
}
return dienstEintraegeToAdd;
}
public static bool RefreshStatusForDay(List<DienstEintragDC> alleDienstEintraege, List<DienstvertretungDC> alleDienstvertretungen, int day,
DateTime pflichtStart, DateTime pflichtEnde)
{
List<DienstEintragDC> eintraegeUndVertretungen = new List<DienstEintragDC>();
List<DienstEintragDC> eintraegeFuerTag = new List<DienstEintragDC>();
eintraegeUndVertretungen.AddRange(alleDienstEintraege);
foreach (var vertretung in alleDienstvertretungen)
{
eintraegeUndVertretungen.Add(new DienstEintragDC()
{
Datum = vertretung.Datum,
DauerInStunden = vertretung.DauerInStunden,
DienstOid = vertretung.DienstOid,
EmployeeOid = vertretung.EmployeeOid,
Endzeit = vertretung.Endzeit,
Notice = vertretung.Notice,
Oid = null,
Startzeit = vertretung.Startzeit,
Version = vertretung.Version,
WohnheimOid = vertretung.WohnheimOid,
Zeile = vertretung.Zeile
});
}
foreach (var eintrag in eintraegeUndVertretungen)
{
if (eintrag.Datum.Day == day)
eintraegeFuerTag.Add(eintrag);
}
if (pflichtStart == pflichtEnde)
return CalculateStatusNew24h(eintraegeFuerTag);
else
{
if (day == 7)
Console.WriteLine();
return CalculateStatusForTimeSpan(eintraegeFuerTag, pflichtStart, pflichtEnde);
}
}
public virtual bool SetEnableDiensteAnFeiertagen()
{
//#if DEBUG
// return false;
//#endif
return true;
}
public virtual bool SetEnableAbwesenheitenAnWochenenden()
{
return true;
}
public static bool SetEnableSorting()
{
return true; // Wenn Bug wieder auf false setzen
}
public static bool SetEnableStatuszeile()
{
return true;
}
#region Methode(n) zum Setzen der Statusanzeige
private static bool CalculateStatusNew24h(List<DienstEintragDC> diensteFuerTag)
{
bool tagAusgefuellt = true;
if (diensteFuerTag.Count != 0)
{
diensteFuerTag = diensteFuerTag.OrderBy(d => d.Startzeit).ToList();
// Ausschlaggebene Variable, da der Status nur auf grün geht, wenn diese Variable 24 ist
double stundenOhneUeberschneidungen = 0;
var vorherigeSchicht = diensteFuerTag[0];
var vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
var vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
for (int i = 0; i < diensteFuerTag.Count; i++)
{
if (diensteFuerTag.Count == 1) //Eine Schicht != 24 Stunden => Schleife kann verlassen werden
{
tagAusgefuellt = false;
break;
}
var dienst = diensteFuerTag[i];
var start = TimeSpan.Parse(dienst.Startzeit);
var ende = TimeSpan.Parse(dienst.Endzeit);
if (start.Hours == 0 && start.Minutes == 0 && start.Seconds == 0 && start == ende)
stundenOhneUeberschneidungen += dienst.DauerInStunden;
else
{
// Identische Schicht kann übersprungen werden
if (dienst.DienstOid == vorherigeSchicht.DienstOid && start == vorherigeSchichtStart && ende == vorherigeSchichtEnde && i != 0)
{
vorherigeSchicht = dienst;
vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
continue;
}
// Im ersten Durchlauf ist dienst == vorherigeSchicht
if (i == 0)
{
stundenOhneUeberschneidungen += dienst.DauerInStunden;
continue;
}
// Start ist früher als Ende, wenn eine Schicht über 0 Uhr hinausgeht => Stunden müssen anders berechnet werden
bool andereBerechnungNoetig = (start < ende) ? false : true;
bool schichtInnerhalbAndererSchicht = false;
// Wenn eine Überschneidung existiert, also die neue Schicht beginnt, bevor die vorherige endet
if (start < vorherigeSchichtEnde)
{
// Wenn Schicht vor Ende der vorherigen Schicht beginnt UND aufhört
if (start < vorherigeSchichtEnde && ende < vorherigeSchichtEnde && !andereBerechnungNoetig)
{
stundenOhneUeberschneidungen += 0;
schichtInnerhalbAndererSchicht = true;
dienst.UmschließenderDienst = vorherigeSchicht;
}
// Schicht startet vor Ende der vorherigen
else
{
// Wenn die Schicht nicht über 0 Uhr hinausgeht, ist die Berechnung normal
if (!andereBerechnungNoetig)
stundenOhneUeberschneidungen += Math.Round((ende - start).TotalHours - (vorherigeSchichtEnde.Hours - start.Hours), 2);
// Geht die Schicht über 0 Uhr hinaus, muss die Berechnung anders durchgeführt werden
else
{
var endeAngepasst = new DateTime(2000, 1, 1, ende.Hours, ende.Minutes, ende.Seconds).AddDays(1);
var startAngepasst = new DateTime(2000, 1, 1, start.Hours, start.Minutes, start.Seconds);
var vorherigeSchichtEndeAngepasst = new DateTime(2000, 1, 1, vorherigeSchichtEnde.Hours, vorherigeSchichtEnde.Minutes, vorherigeSchichtEnde.Seconds);
stundenOhneUeberschneidungen += Math.Round((endeAngepasst - startAngepasst).TotalHours - (vorherigeSchichtEndeAngepasst - startAngepasst).TotalHours, 2);
}
}
}
// Wenn keine Überschneidung existiert, können einfach die Stunden aufaddiert werden
else
stundenOhneUeberschneidungen += dienst.DauerInStunden;
// Wenn die aktuelle Schicht die letzte ist
if (i == diensteFuerTag.Count - 1)
{
// Endet die letzte Schicht früher als die erste Schicht und die 24h vorher nicht voll waren, sind keine 24h ausgefüllt
if (ende < TimeSpan.Parse(diensteFuerTag[0].Startzeit) /*&& stundenOhneUeberschneidungen < 24*/)
{
tagAusgefuellt = false;
break;
}
}
// Wenn die aktuelle Schicht später beginnt als die vorherige endet, also eine Lücke da ist
if (start > vorherigeSchichtEnde /* && dienst.Oid != vorherigeSchicht.Oid*/)
{
if (vorherigeSchicht.UmschließenderDienst != null)
{
if (TimeSpan.Parse(vorherigeSchicht.UmschließenderDienst.Endzeit) < start)
{
tagAusgefuellt = false;
break;
}
}
else
{
if (!schichtInnerhalbAndererSchicht && stundenOhneUeberschneidungen < 24)
{
tagAusgefuellt = false;
break;
}
}
}
//vorherigeSchicht = dienst;
//vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
//vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
}
vorherigeSchicht = dienst;
vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
}
if (stundenOhneUeberschneidungen < 24) //Wenn nach durchgehen aller Schichten für Tag nicht 24h erreicht wurden
tagAusgefuellt = false;
}
else //Wenn keine Schichten für den Tag vorhanden sind
tagAusgefuellt = false;
return tagAusgefuellt;
}
private static bool CalculateStatusForTimeSpan(List<DienstEintragDC> diensteFuerTag, DateTime PflichtStart, DateTime PflichtEnde)
{
bool tagAusgefuellt = true;
bool keineSchichtenOhneZeiten = false;
if (diensteFuerTag.Count != 0)
{
foreach (var d in diensteFuerTag)
{
var start = d.Startzeit.Split(':');
d.Datum = new DateTime(d.Datum.Year, d.Datum.Month, d.Datum.Day, Convert.ToInt32(start[0]), Convert.ToInt32(start[1]), 0);
}
diensteFuerTag = diensteFuerTag.OrderBy(d => d.Datum).ToList();
double minStundenFuerGruenenStatus = (PflichtEnde - PflichtStart).TotalHours;
double stundenOhneUeberschneidungen = 0;
var startArray = diensteFuerTag[0].Startzeit.Split(':');
var dienstStart = new DateTime(PflichtStart.Year, PflichtStart.Month, PflichtStart.Day,
Convert.ToInt32(startArray[0]), Convert.ToInt32(startArray[1]), 0);
// Wenn es eine einzige Schicht gibt, die nicht nur die Dauer hat, müssen zusätzliche Faktoren gecheckt werden
if (diensteFuerTag.Any(d => TimeSpan.Parse(d.Startzeit).Hours != 0 || TimeSpan.Parse(d.Startzeit).Minutes != 0 ||
TimeSpan.Parse(d.Endzeit).Hours != 0 || TimeSpan.Parse(d.Endzeit).Minutes != 0))
{
// Wenn kein Dienst die Startzeit der Pflichtbesetzung umschließt oder die Startzeit als Schichtbeginn hat, dann ist der Tag nicht ausgefüllt, sofern keine Schicht existiert,
// die nur Stunden hat
if (!diensteFuerTag.Any(d => d.Startzeit == "00:00" && d.Startzeit == d.Endzeit))
keineSchichtenOhneZeiten = true;
if (!diensteFuerTag.Any(d => TimeSpan.Parse(d.Startzeit) <= PflichtStart.TimeOfDay &&
TimeSpan.Parse(d.Endzeit) >= PflichtStart.TimeOfDay) && keineSchichtenOhneZeiten)
{
tagAusgefuellt = false;
}
// Wenn der zeitlich erste Dienst später beginnt als die Zeit, in der wer da sein muss, ist der Tag nicht ausgefüllt
if (dienstStart > PflichtStart)
tagAusgefuellt = false;
//bool dienstLaengerAlsPflichtbesetzungsEnde = false;
//foreach (var dienst in diensteFuerTag)
//{
// var dienstEndeTime = TimeSpan.Parse(dienst.Endzeit);
// if (dienstEndeTime > PflichtEnde.TimeOfDay)
// dienstLaengerAlsPflichtbesetzungsEnde = true;
//}
}
var vorherigeSchicht = diensteFuerTag[0];
var vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
var vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
for (int i = 0; i < diensteFuerTag.Count; i++)
{
var dienst = diensteFuerTag[i];
var start = TimeSpan.Parse(dienst.Startzeit);
var ende = TimeSpan.Parse(dienst.Endzeit);
// Wenn beide Zeiten 00:00 sind, müssen nur die Stunden aufaddiert werden
if (start.Hours == 0 && start.Minutes == 0 && start.Seconds == 0 && start == ende)
stundenOhneUeberschneidungen += dienst.DauerInStunden;
else
{
// Identische Schicht kann übersprungen werden
if (dienst.DienstOid == vorherigeSchicht.DienstOid && start == vorherigeSchichtStart && ende == vorherigeSchichtEnde && i != 0)
{
vorherigeSchicht = dienst;
vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
continue;
}
// Im ersten Durchlauf ist dienst == vorherigeSchicht
if (i == 0)
{
// Wenn die erste Schicht vor Pflichtbesetzungsstart beginnt, zählen die Stunden erst ab dem Pflichtbesetzungsstart
if (start < PflichtStart.TimeOfDay)
{
// Wenn das Ende auch vor Pflichtbesetzungsstart ist, sind es 0 Stunden
if (ende <= PflichtStart.TimeOfDay)
continue;
start = PflichtStart.TimeOfDay;
stundenOhneUeberschneidungen += (ende - start).TotalHours;
continue;
}
stundenOhneUeberschneidungen += dienst.DauerInStunden;
continue;
}
if (keineSchichtenOhneZeiten)
{
if (start > vorherigeSchichtEnde)
tagAusgefuellt = false;
}
// Start ist früher als Ende, wenn eine Schicht über 0 Uhr hinausgeht => Stunden müssen anders berechnet werden
bool andereBerechnungNoetig = (start < ende) ? false : true;
bool schichtInnerhalbAndererSchicht = false;
// Wenn eine Überschneidung existiert, also die neue Schicht beginnt, bevor die vorherige endet
if (start < vorherigeSchichtEnde)
{
// Wenn Schicht vor Ende der vorherigen Schicht beginnt UND aufhört
if (start < vorherigeSchichtEnde && ende < vorherigeSchichtEnde && !andereBerechnungNoetig)
{
stundenOhneUeberschneidungen += 0;
schichtInnerhalbAndererSchicht = true;
dienst.UmschließenderDienst = vorherigeSchicht;
}
// Wenn Schichtende nach dem Ende der Pflichtbesetzung ist
else if (start < PflichtEnde.TimeOfDay && ende > PflichtEnde.TimeOfDay)
{
// Wenn die Schicht nicht über 0 Uhr hinausgeht, ist die Berechnung normal
if (!andereBerechnungNoetig)
{
ende = PflichtEnde.TimeOfDay;
stundenOhneUeberschneidungen += Math.Round((ende - start).TotalHours - (vorherigeSchichtEnde.Hours - start.Hours), 2);
}
}
// Schicht startet vor Ende der vorherigen
else if (start < vorherigeSchichtEnde && ende > vorherigeSchichtEnde)
{
// Wenn die Schicht nicht über 0 Uhr hinausgeht, ist die Berechnung normal
if (!andereBerechnungNoetig)
stundenOhneUeberschneidungen += Math.Round((ende - start).TotalHours - (vorherigeSchichtEnde - start).TotalHours, 2);
// Geht die Schicht über 0 Uhr hinaus, muss die Berechnung anders durchgeführt werden
else
{
var endeAngepasst = new DateTime(2000, 1, 1, ende.Hours, ende.Minutes, ende.Seconds).AddDays(1);
var startAngepasst = new DateTime(2000, 1, 1, start.Hours, start.Minutes, start.Seconds);
var vorherigeSchichtEndeAngepasst = new DateTime(2000, 1, 1, vorherigeSchichtEnde.Hours, vorherigeSchichtEnde.Minutes, vorherigeSchichtEnde.Seconds);
stundenOhneUeberschneidungen += Math.Round((endeAngepasst - startAngepasst).TotalHours - (vorherigeSchichtEndeAngepasst - startAngepasst).TotalHours, 2);
}
}
}
// Wenn keine Überschneidung existiert, können einfach die Stunden aufaddiert werden
else
{
if (start < PflichtEnde.TimeOfDay && ende > PflichtEnde.TimeOfDay)
{
ende = PflichtEnde.TimeOfDay;
stundenOhneUeberschneidungen += (ende - start).TotalHours;
}
else
stundenOhneUeberschneidungen += dienst.DauerInStunden;
}
// Wenn die aktuelle Schicht die letzte ist
if (i == diensteFuerTag.Count - 1)
{
// Endet die letzte Schicht früher als die erste Schicht und die Stunden vorher nicht voll waren, sind keine 24h ausgefüllt
if (stundenOhneUeberschneidungen < minStundenFuerGruenenStatus)
{
tagAusgefuellt = false;
break;
}
}
// Wenn die aktuelle Schicht später beginnt als die vorherige endet, also eine Lücke da ist
if (vorherigeSchichtStart.Hours != 0 && vorherigeSchichtStart.Minutes != 0 && vorherigeSchichtEnde.Hours != 0 && vorherigeSchichtEnde.Minutes != 0)
{
if (start > vorherigeSchichtEnde && dienst.Oid != vorherigeSchicht.Oid)
{
if (vorherigeSchicht.UmschließenderDienst != null)
{
if (TimeSpan.Parse(vorherigeSchicht.UmschließenderDienst.Endzeit) < start)
{
tagAusgefuellt = false;
break;
}
}
else
{
if (!schichtInnerhalbAndererSchicht && stundenOhneUeberschneidungen < minStundenFuerGruenenStatus)
{
tagAusgefuellt = false;
break;
}
}
}
}
//vorherigeSchicht = dienst;
//vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
//vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
}
vorherigeSchicht = dienst;
vorherigeSchichtStart = TimeSpan.Parse(vorherigeSchicht.Startzeit);
vorherigeSchichtEnde = TimeSpan.Parse(vorherigeSchicht.Endzeit);
}
if (stundenOhneUeberschneidungen < minStundenFuerGruenenStatus) //Wenn nach durchgehen aller Schichten für Tag nicht x Stunden erreicht wurden
{
tagAusgefuellt = false;
}
foreach (var d in diensteFuerTag)
d.Datum = new DateTime(d.Datum.Year, d.Datum.Month, d.Datum.Day, 0, 0, 0);
}
else //Wenn keine Schichten für den Tag vorhanden sind
tagAusgefuellt = false;
return tagAusgefuellt;
}
#endregion
public static ContractDC GetContract(List<ContractDC> contracts, DateTime absDatum) => contracts.FirstOrDefault(x => (!x.EntryDate.HasValue ||
x.EntryDate.Value <= absDatum.Date) &&
(!x.ContractEndDate.HasValue || x.ContractEndDate.Value >= absDatum.Date));
}
}