564 lines
22 KiB
C#
564 lines
22 KiB
C#
using System;
|
|
using BeWo.Report.ReportObjects;
|
|
using BeWo.Report;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Data.Access;
|
|
using System.Collections.Generic;
|
|
using BS.Shared.Core;
|
|
using BeWo.Service.ServiceImplementations;
|
|
|
|
namespace BeWo.WohnhelferRemscheidReports
|
|
{
|
|
public partial class Mitarbeiterauswertung : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<QueryRO>
|
|
{
|
|
private decimal maxWochenstunden = 39;
|
|
|
|
|
|
|
|
//Zeile Gesamt mit "FLS Stunden Soll"
|
|
public Mitarbeiterauswertung()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public void SetReportDataSource(QueryRO pRO)
|
|
{
|
|
InitDataSource(pRO);
|
|
this.bindingSource1.DataSource = pRO;
|
|
}
|
|
|
|
private void InitDataSource(QueryRO ro)
|
|
{
|
|
IList<Employee> employees = DAOFactory.GenericDAO.GetAllActiveAndArchived<Employee>();
|
|
Dictionary<long, Employee> empDict = new Dictionary<long, Employee>();
|
|
foreach (var item in employees)
|
|
{
|
|
empDict.Add(item.Oid.Value, item);
|
|
}
|
|
DateTime monat = DateTime.MinValue;
|
|
|
|
decimal sollGesamt = 0;
|
|
decimal relationGesamt = 0;
|
|
decimal gesamtGesamt = 0;
|
|
decimal flsSollGesamt = 0;
|
|
decimal flsPlusMinusGesamt = 0;
|
|
decimal flsIstGesamt = 0;
|
|
|
|
|
|
foreach (BeWo.Report.ReportObjects.QueryRO.Row row in ro.Rows)
|
|
{
|
|
if (monat == DateTime.MinValue)
|
|
{
|
|
monat = DateTime.Parse(row.Field2.ToString());
|
|
}
|
|
long oid = 0;
|
|
if (Int64.TryParse(row.Field1.ToString(), out oid))
|
|
{
|
|
if (empDict.ContainsKey(oid))
|
|
{
|
|
Employee emp = empDict[oid];
|
|
|
|
int arbeitstage = GetArbeitstageImMonat(row.Field2);
|
|
|
|
decimal bu = 0;
|
|
|
|
row.Field2 = emp.Person.LastName;
|
|
row.Field3 = null;
|
|
|
|
Contract c = emp.GetValidContractForDate(DateTime.Now);
|
|
|
|
bool istMitMehrstunden = false;
|
|
bool istHonorarkraft = false;
|
|
|
|
if (c != null)
|
|
{
|
|
if (c.WeeklyTotalHours.HasValue)
|
|
{
|
|
if (c.WeeklyTotalHours.HasValue)
|
|
{
|
|
bu = c.WeeklyTotalHours.Value / maxWochenstunden;
|
|
}
|
|
}
|
|
|
|
EmploymentType et = c.EmploymentType;
|
|
if (et != null)
|
|
{
|
|
if (et.Oid.Value == 19)
|
|
istMitMehrstunden = true;
|
|
else if (et.Oid.Value == 18)
|
|
istHonorarkraft = true;
|
|
}
|
|
if (c.EntryDate > monat)
|
|
bu = 0;
|
|
} else
|
|
{
|
|
row.Field20 = "NoContract";
|
|
}
|
|
|
|
decimal flsIst = 0;
|
|
decimal mittelbarIst = 0;
|
|
|
|
DateTimeSpan span = new DateTimeSpan();
|
|
span.StartDate = monat;
|
|
|
|
span.EndDate = monat.Date.AddMonths(1);
|
|
|
|
//IList<ServiceRecord> records2 = DAOFactory.SearchDAO.FindEmployeeServiceRecords(emp.Oid.Value, span, null);
|
|
|
|
IList<ServiceRecord> records = DAOFactory.SearchDAO.FindServiceRecords(emp.Oid, null);
|
|
records = AnalysisServiceImp.FilterActiveServiceRecords(records);
|
|
foreach (var item in records)
|
|
{
|
|
//if (item.ServiceDescription != null && item.ServiceDescription.ServiceCategory != null && item.ServiceDescription.ServiceCategory.Name.ToLower().IndexOf("fehlzeit") >= 0)
|
|
//{
|
|
if (!IsServiceRecordFehlzeit(item))
|
|
{
|
|
if (item.Start.Value >= monat && item.Start.Value < monat.AddMonths(1))
|
|
{
|
|
if (item.ServiceDescription != null &&
|
|
item.ServiceDescription.ServiceCategory != null &&
|
|
item.ServiceDescription.ServiceCategory.IsBillable)
|
|
flsIst += item.RoundedDuration;
|
|
else
|
|
mittelbarIst += item.RoundedDuration;
|
|
}
|
|
}
|
|
//}
|
|
}
|
|
flsIst /= 60m;
|
|
mittelbarIst /= 60m;
|
|
|
|
row.Field6 = String.Format("{0:0.00}", flsIst);
|
|
row.Field7 = String.Format("{0:0.00}", mittelbarIst);
|
|
//Decimal.TryParse(row.Field6.ToString(), out flsIst);
|
|
//Decimal.TryParse(row.Field7.ToString(), out mittelbarIst);
|
|
|
|
row.Field3 = String.Format("{0:0.00}", bu);
|
|
|
|
decimal flsSollGesamtS4 = arbeitstage * (maxWochenstunden / 5) * bu;
|
|
|
|
row.Field4 = String.Format("{0:0.00}", flsSollGesamtS4);
|
|
|
|
IList<AbsenceTime> absenceTimes = emp.AbsenceTimes;
|
|
|
|
|
|
|
|
|
|
|
|
decimal? fehlZeitenS5 = GetFehlzeiten(records, monat);
|
|
row.Field5 = String.Format("{0:0.00}", fehlZeitenS5);
|
|
|
|
decimal? urlaubS6 = GetUrlaubKrankheit(absenceTimes, monat);
|
|
|
|
row.Field6 = String.Format("{0:0.00}", urlaubS6);
|
|
decimal tatsaechlicheSollStdS7 = flsSollGesamtS4;
|
|
if (fehlZeitenS5.HasValue)
|
|
tatsaechlicheSollStdS7 -= fehlZeitenS5.Value;
|
|
if (urlaubS6.HasValue)
|
|
tatsaechlicheSollStdS7 -= (urlaubS6.Value * (maxWochenstunden / 5) * bu);
|
|
row.Field7 = String.Format("{0:0.00}", tatsaechlicheSollStdS7);
|
|
|
|
decimal flsSollS8 = tatsaechlicheSollStdS7;
|
|
if (c != null && c.WeeklyFLS.HasValue && c.WeeklyTotalHours.HasValue && c.WeeklyTotalHours.Value != 0)
|
|
flsSollS8 = tatsaechlicheSollStdS7 * (c.WeeklyFLS.Value / c.WeeklyTotalHours.Value);
|
|
|
|
row.Field8 = String.Format("{0:0.00}", flsSollS8);
|
|
row.Field9 = String.Format("{0:0.00}", flsIst);
|
|
row.Field10 = String.Format("{0:0.00}", flsIst - flsSollS8);
|
|
row.Field11 = String.Format("{0:0.00}", flsIst + mittelbarIst);
|
|
if (flsIst + mittelbarIst > 0)
|
|
{
|
|
row.Field12 = String.Format("{0:0.00}% ", (flsIst / (flsIst + mittelbarIst)) * 100);
|
|
// if (flsSollS8 != 0)
|
|
// row.Field12 += String.Format("{0:0.00}%", ((flsIst * (30m / 39m)) / flsSollS8) * 100);
|
|
// else
|
|
// row.Field12 += "";
|
|
|
|
|
|
}
|
|
|
|
decimal stundengesamt = flsIst + mittelbarIst;
|
|
decimal? ueberstunden = stundengesamt - tatsaechlicheSollStdS7;
|
|
decimal? ueberstundenVormonat;
|
|
decimal? mehrstunden = null;
|
|
decimal? mehrstundenVormonat = null;
|
|
|
|
|
|
BerechneÜberstundenBis(emp, monat, bu, istMitMehrstunden, out ueberstundenVormonat, out mehrstundenVormonat);
|
|
|
|
|
|
if (istMitMehrstunden)
|
|
{
|
|
decimal maxMonat = arbeitstage * (maxWochenstunden / 5);
|
|
if (fehlZeitenS5.HasValue)
|
|
maxMonat -= fehlZeitenS5.Value;
|
|
if (urlaubS6.HasValue)
|
|
maxMonat -= (urlaubS6.Value * (maxWochenstunden / 5) * bu);
|
|
if (stundengesamt > maxMonat)
|
|
{
|
|
ueberstunden = stundengesamt - maxMonat;
|
|
mehrstunden = maxMonat - tatsaechlicheSollStdS7;
|
|
}
|
|
else
|
|
{
|
|
mehrstunden = ueberstunden;
|
|
ueberstunden = null;
|
|
|
|
}
|
|
}
|
|
|
|
row.Field13 = String.Format("{0:0.00}", ueberstunden);
|
|
row.Field14 = String.Format("{0:0.00}", ueberstundenVormonat);
|
|
row.Field15 = String.Format("{0:0.00}", ueberstundenVormonat + ueberstunden);
|
|
|
|
row.Field16 = String.Format("{0:0.00}", mehrstunden);
|
|
row.Field17 = String.Format("{0:0.00}", mehrstundenVormonat);
|
|
row.Field18 = String.Format("{0:0.00}", mehrstundenVormonat + mehrstunden);
|
|
|
|
if (istHonorarkraft)
|
|
{
|
|
row.Field3 = "";
|
|
row.Field4 = "";
|
|
row.Field5 = "";
|
|
row.Field6 = "";
|
|
row.Field7 = "";
|
|
row.Field8 = "";
|
|
//row.Field9 = "";
|
|
//row.Field10 = "";
|
|
//row.Field11 = "";
|
|
//row.Field12 = "";
|
|
row.Field13 = "";
|
|
row.Field14 = "";
|
|
row.Field15 = "";
|
|
row.Field16 = "";
|
|
row.Field17 = "";
|
|
row.Field18 = "";
|
|
}
|
|
|
|
|
|
sollGesamt += tatsaechlicheSollStdS7;
|
|
flsSollGesamt += flsSollS8;
|
|
flsIstGesamt += flsIst;
|
|
flsPlusMinusGesamt += (flsIst - flsSollS8);
|
|
gesamtGesamt += flsIst + mittelbarIst;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
cellSollGesamt.Text = String.Format("{0:0.00}", sollGesamt); //7
|
|
cellFLSSollGesamt.Text = String.Format("{0:0.00}", flsSollGesamt); //8
|
|
cellFLSIstGesamt.Text = String.Format("{0:0.00}", flsIstGesamt); //9
|
|
cellFLSPlusMinusGesamt.Text = String.Format("{0:0.00}", flsPlusMinusGesamt);//10
|
|
cellGesamtGesamt.Text = String.Format("{0:0.00}", gesamtGesamt);//11
|
|
|
|
|
|
if (flsSollGesamt != 0)
|
|
cellRelationGesamt.Text += String.Format("{0:0.00}%", ((flsIstGesamt * (30m / 39m)) / flsSollGesamt) * 100m);
|
|
else
|
|
cellRelationGesamt.Text += "";
|
|
|
|
|
|
lblMonat.Text = String.Format("{0:MMMM yy}", monat);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void BerechneÜberstundenBis(Employee emp, DateTime monat, decimal bu, bool mehrstundenBerechnen, out decimal? ueberstunden, out decimal? mehrstunden)
|
|
{
|
|
ueberstunden = null;
|
|
mehrstunden = null;
|
|
|
|
IList<ServiceRecord> records = DAOFactory.SearchDAO.FindServiceRecords(emp.Oid, null);
|
|
records = AnalysisServiceImp.FilterActiveServiceRecords(records);
|
|
|
|
//decimal minutenGesamt = 0;
|
|
//decimal soll = 0;
|
|
|
|
Contract c = GetFirstContract(emp);
|
|
|
|
//decimal stundenAbwesend = 0;
|
|
|
|
if (c != null && c.EntryDate.HasValue)
|
|
{
|
|
DateTime start = c.EntryDate.Value;
|
|
|
|
while (start < monat)
|
|
{
|
|
decimal minutenMonat = 0;
|
|
DateTime ende = start.AddMonths(1);
|
|
ende = new DateTime(ende.Year, ende.Month, 1);
|
|
|
|
foreach (var item in records)
|
|
{
|
|
if (!IsServiceRecordFehlzeit(item))
|
|
{
|
|
if (item.Start.HasValue && item.Start >= start && item.Start < ende)
|
|
{
|
|
minutenMonat += item.RoundedDuration;
|
|
}
|
|
}
|
|
}
|
|
|
|
int arbeitstage = GetArbeitstageImBereich(start, ende);
|
|
|
|
decimal maxSollMonat = arbeitstage * (maxWochenstunden / 5);
|
|
decimal sollMitarbeiter = maxSollMonat * bu;
|
|
|
|
decimal? urlaub = GetUrlaubKrankheit(emp.AbsenceTimes, start);
|
|
decimal? fehlzeit = GetFehlzeiten(records, start);
|
|
|
|
if (fehlzeit.HasValue)
|
|
{
|
|
sollMitarbeiter -= fehlzeit.Value;
|
|
maxSollMonat -= fehlzeit.Value;
|
|
}
|
|
if (urlaub.HasValue)
|
|
{
|
|
sollMitarbeiter -= (urlaub.Value * (maxWochenstunden / 5) * bu);
|
|
maxSollMonat -= (urlaub.Value * (maxWochenstunden / 5) * bu);
|
|
}
|
|
|
|
decimal stundenMonat = minutenMonat /= 60m;
|
|
|
|
|
|
|
|
if (mehrstundenBerechnen)
|
|
{
|
|
if (!mehrstunden.HasValue)
|
|
mehrstunden = 0;
|
|
|
|
if (stundenMonat > maxSollMonat)
|
|
{
|
|
if (!ueberstunden.HasValue)
|
|
ueberstunden = 0;
|
|
ueberstunden += (stundenMonat - maxSollMonat);
|
|
mehrstunden += (maxSollMonat - sollMitarbeiter);
|
|
}
|
|
else
|
|
{
|
|
mehrstunden += (stundenMonat - sollMitarbeiter);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!ueberstunden.HasValue)
|
|
ueberstunden = 0;
|
|
ueberstunden += stundenMonat - sollMitarbeiter;
|
|
}
|
|
|
|
|
|
start = ende;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
private Contract GetFirstContract(Employee emp)
|
|
{
|
|
DateTime minDate = DateTime.MaxValue;
|
|
Contract contractWithMinDate = null;
|
|
if (emp.Contracts != null)
|
|
{
|
|
foreach (var item in emp.Contracts)
|
|
{
|
|
if (!item.EntryDate.HasValue)
|
|
{
|
|
contractWithMinDate = item;
|
|
minDate = DateTime.MinValue;
|
|
}
|
|
else if (item.EntryDate.Value < minDate)
|
|
{
|
|
minDate = item.EntryDate.Value;
|
|
contractWithMinDate = item;
|
|
}
|
|
}
|
|
}
|
|
return contractWithMinDate;
|
|
}
|
|
|
|
private decimal? GetUrlaubKrankheit(IList<AbsenceTime> absenceTimes, DateTime monat)
|
|
{
|
|
decimal? tage = null;
|
|
if (absenceTimes != null)
|
|
{
|
|
foreach (var item in absenceTimes)
|
|
{
|
|
//if (!String.IsNullOrEmpty(item.AbsenceReason.Description) && (item.AbsenceReason.Description.ToLower().IndexOf("urlaub") >= 0
|
|
// || item.AbsenceReason.Description.ToLower().IndexOf("krank") >= 0))
|
|
//{
|
|
|
|
|
|
DateTimeSpan span = new DateTimeSpan();
|
|
|
|
span.StartDate = monat;
|
|
|
|
if (item.Start.HasValue && item.Start.Value > span.StartDate)
|
|
{
|
|
span.StartDate = item.Start.Value;
|
|
}
|
|
span.EndDate = monat.AddMonths(1);
|
|
if (item.End.HasValue && item.End.Value.Date.AddDays(1) < span.EndDate)
|
|
{
|
|
span.EndDate = item.End.Value.Date.AddDays(1);
|
|
}
|
|
if (span.EndDate >= monat && span.StartDate < monat.AddMonths(1))
|
|
{
|
|
//if (item.AbsenceReason.)
|
|
if (!tage.HasValue)
|
|
tage = 0;
|
|
|
|
tage += (decimal)span.GetTimeSpan().TotalHours;
|
|
}
|
|
//}
|
|
}
|
|
}
|
|
if (tage.HasValue)
|
|
tage /= 24;
|
|
return tage;
|
|
}
|
|
|
|
private decimal? GetFehlzeiten(IList<ServiceRecord> records, DateTime monat)
|
|
{
|
|
decimal? stunden = null;
|
|
decimal minuten = 0;
|
|
if (records != null)
|
|
{
|
|
foreach (var item in records)
|
|
{
|
|
if (IsServiceRecordFehlzeit(item))
|
|
{
|
|
if (item.Start.Value >= monat && item.Start.Value < monat.AddMonths(1))
|
|
minuten += item.RoundedDuration;
|
|
}
|
|
}
|
|
}
|
|
if (minuten != 0)
|
|
stunden = minuten / 60;
|
|
return stunden;
|
|
}
|
|
|
|
|
|
|
|
private int GetArbeitstageImMonat(object datum)
|
|
{
|
|
DateTime dt = DateTime.Now;
|
|
if (DateTime.TryParse(datum.ToString(), out dt))
|
|
{
|
|
DateTime start = new DateTime(dt.Year, dt.Month, 1);
|
|
|
|
DateTime end = start.AddMonths(1);
|
|
|
|
return GetArbeitstageImBereich(start, end);
|
|
}
|
|
return 0;
|
|
}
|
|
private int GetArbeitstageImBereich(DateTime von, DateTime bis)
|
|
{
|
|
DateTime dt = DateTime.Now;
|
|
|
|
DateTime start = von;
|
|
DateTime end = bis;
|
|
|
|
TimeSpan ts = end.Subtract(start);
|
|
|
|
int maxDays = (int)ts.TotalDays;
|
|
|
|
while (start < end)
|
|
{
|
|
if (start.DayOfWeek == DayOfWeek.Saturday || start.DayOfWeek == DayOfWeek.Sunday)
|
|
{
|
|
maxDays--;
|
|
}
|
|
else
|
|
{
|
|
if (IstFeiertag(start))
|
|
maxDays--;
|
|
}
|
|
start = start.AddDays(1);
|
|
}
|
|
return maxDays;
|
|
|
|
}
|
|
|
|
private bool IstFeiertag(DateTime start)
|
|
{
|
|
List<DateTime> feiertage = GetFeiertage(start.Year);
|
|
|
|
foreach (var dateTime in feiertage)
|
|
{
|
|
if (start == dateTime)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private List<DateTime> GetFeiertage(int year)
|
|
{
|
|
List<DateTime> list = new List<DateTime>();
|
|
list.Add(new DateTime(year, 1, 1)); // "Neujahr"));
|
|
//list.Add(new DateTime(year, 1, 6)); // , "Heilige Drei Könige"));
|
|
list.Add(new DateTime(year, 5, 1)); // , "Tag der Arbeit"));
|
|
//list.Add(new DateTime(year, 8, 15)); // , "Mariä Himmelfahrt"));
|
|
list.Add(new DateTime(year, 10, 3)); // , "Tag der dt. Einheit"));
|
|
//list.Add(new DateTime(year, 10, 31)); // , "Reformationstag"));
|
|
|
|
if (year == 2017)
|
|
{
|
|
list.Add(new DateTime(year, 10, 31)); // , "Reformationstag"));
|
|
}
|
|
|
|
list.Add(new DateTime(year, 11, 1)); // , "Allerheiligen "));
|
|
list.Add(new DateTime(year, 12, 24)); // , "Heilig Abend"));
|
|
list.Add(new DateTime(year, 12, 25)); // , "1. Weihnachtstag"));
|
|
list.Add(new DateTime(year, 12, 26)); // , "2. Weihnachtstag"));
|
|
DateTime osterSonntag = GetOsterSonntag(year);
|
|
//list.Add(osterSonntag); // , "Ostersonntag"));
|
|
//list.Add(osterSonntag.AddDays(-3)); // , "Gründonnerstag"));
|
|
list.Add(osterSonntag.AddDays(-48)); // , "Rosenmonatg"));
|
|
list.Add(osterSonntag.AddDays(-2)); // , "Karfreitag"));
|
|
list.Add(osterSonntag.AddDays(1)); // , "Ostermontag"));
|
|
list.Add(osterSonntag.AddDays(39)); // , "Christi Himmelfahrt"));
|
|
//list.Add(osterSonntag.AddDays(49)); // , "Pfingstsonntag"));
|
|
list.Add(osterSonntag.AddDays(50)); // , "Pfingstmontag"));
|
|
list.Add(osterSonntag.AddDays(60)); // , "Fronleichnam"));
|
|
|
|
return list;
|
|
}
|
|
|
|
private 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);
|
|
|
|
}
|
|
|
|
private bool IsServiceRecordFehlzeit(ServiceRecord sr)
|
|
{
|
|
if (sr.ServiceDescription != null && sr.ServiceDescription.ServiceCategory != null && sr.ServiceDescription.ServiceCategory.Name.ToLower().IndexOf("fehlzeit") >= 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|