925 lines
44 KiB
C#
925 lines
44 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using BeWo.Report;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Service.DCEntityMapper;
|
|
using BeWo.Service.Plugins;
|
|
using BS.Shared.Core;
|
|
using BS.Shared;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Services;
|
|
using System.Linq;
|
|
|
|
namespace BeWo.Report.ReportObjects
|
|
{
|
|
public class AuslastungBerechnung
|
|
{
|
|
private Dictionary<String, MitarbeiterauslastungRO.SupportConceptDetail> betreuungDict;
|
|
public AuslastungBerechnung()
|
|
{
|
|
betreuungDict = new Dictionary<String, MitarbeiterauslastungRO.SupportConceptDetail>();
|
|
}
|
|
|
|
public virtual void CreateReport(MitarbeiterauslastungRO ro)
|
|
{
|
|
CreateEmployeeDetails(ro);
|
|
CreateEmployeeTotals(ro);
|
|
CreateTeamDetails(ro);
|
|
CreateTotals(ro);
|
|
}
|
|
|
|
private void CreateEmployeeTotals(MitarbeiterauslastungRO ro)
|
|
{
|
|
foreach (var empDetail in ro.EmployeeDetailList)
|
|
{
|
|
foreach (var scd in empDetail.SupportConceptDetailList)
|
|
{
|
|
scd.DirectIst /= 60;
|
|
scd.MittelbarIst /= 60;
|
|
scd.IstKw1 /= 60;
|
|
scd.IstKw2 /= 60;
|
|
scd.IstKw3 /= 60;
|
|
scd.IstKw4 /= 60;
|
|
scd.IstKw5 /= 60;
|
|
scd.IstKw6 /= 60;
|
|
|
|
if (scd.EndDate.HasValue && scd.EndDate.Value.AddDays(1) >= ro.ReportEndDate)
|
|
{
|
|
empDetail.DirectIst += scd.DirectIst;
|
|
empDetail.MittelbarIst += scd.MittelbarIst;
|
|
empDetail.ApprovedHoursPerWeekTotal += scd.ApprovedHoursPerWeekTotal;
|
|
empDetail.ApprovedHoursPerWeek += scd.ApprovedHoursPerWeek;
|
|
empDetail.ApprovedHoursPerWeekWithRateFactorTotal += scd.ApprovedHoursPerWeekWithRateFactorTotal;
|
|
empDetail.ApprovedHoursPerWeekWithRateFactor += scd.ApprovedHoursPerWeekWithRateFactor;
|
|
empDetail.ApprovedHoursPerMonthTotal += scd.ApprovedHoursPerMonthTotal;
|
|
empDetail.ApprovedHoursPerMonth += scd.ApprovedHoursPerMonth;
|
|
empDetail.ApprovedHoursPerMonthWithRateFactorTotal += scd.ApprovedHoursPerMonthWithRateFactorTotal;
|
|
empDetail.ApprovedHoursPerMonthWithRateFactor += scd.ApprovedHoursPerMonthWithRateFactor;
|
|
empDetail.FreiProWoche += scd.FreiProWoche;
|
|
empDetail.FreiProMonat += scd.FreiProMonat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void CreateTotals(MitarbeiterauslastungRO ro)
|
|
{
|
|
foreach (var empDetail in ro.EmployeeDetailList)
|
|
{
|
|
ro.DirectIst += empDetail.DirectIst;
|
|
ro.MittelbarIst += empDetail.MittelbarIst;
|
|
ro.ApprovedHoursPerWeekTotal += empDetail.ApprovedHoursPerWeekTotal;
|
|
ro.ApprovedHoursPerWeek += empDetail.ApprovedHoursPerWeek;
|
|
ro.ApprovedHoursPerWeekWithRateFactorTotal += empDetail.ApprovedHoursPerWeekWithRateFactorTotal;
|
|
ro.ApprovedHoursPerWeekWithRateFactor += empDetail.ApprovedHoursPerWeekWithRateFactor;
|
|
ro.ApprovedHoursPerMonthTotal += empDetail.ApprovedHoursPerMonthTotal;
|
|
ro.ApprovedHoursPerMonth += empDetail.ApprovedHoursPerMonth;
|
|
ro.ApprovedHoursPerMonthWithRateFactorTotal += empDetail.ApprovedHoursPerMonthWithRateFactorTotal;
|
|
ro.ApprovedHoursPerMonthWithRateFactor += empDetail.ApprovedHoursPerMonthWithRateFactor;
|
|
|
|
}
|
|
|
|
if (ro.ApprovedHoursPerWeek != 0)
|
|
ro.RelationIstSoll = (ro.DirectIst / ro.ApprovedHoursPerWeek) * 100m;
|
|
|
|
if (ro.DirectIst + ro.MittelbarIst != 0)
|
|
ro.RelationDirectToMittelbar = (ro.DirectIst / (ro.DirectIst + ro.MittelbarIst)) * 100;
|
|
}
|
|
|
|
public virtual void CreateTeamDetails(MitarbeiterauslastungRO ro)
|
|
{
|
|
foreach (var teamDetail in ro.TeamDetailList)
|
|
{
|
|
foreach (var empDetail in teamDetail.EmployeeDetailList)
|
|
{
|
|
teamDetail.DirectIst += empDetail.DirectIst;
|
|
teamDetail.MittelbarIst += empDetail.MittelbarIst;
|
|
teamDetail.ApprovedHoursPerWeekTotal += empDetail.ApprovedHoursPerWeekTotal;
|
|
teamDetail.ApprovedHoursPerWeek += empDetail.ApprovedHoursPerWeek;
|
|
teamDetail.ApprovedHoursPerWeekWithRateFactorTotal += empDetail.ApprovedHoursPerWeekWithRateFactorTotal;
|
|
teamDetail.ApprovedHoursPerWeekWithRateFactor += empDetail.ApprovedHoursPerWeekWithRateFactor;
|
|
teamDetail.ApprovedHoursPerMonthTotal += empDetail.ApprovedHoursPerMonthTotal;
|
|
teamDetail.ApprovedHoursPerMonth += empDetail.ApprovedHoursPerMonth;
|
|
teamDetail.ApprovedHoursPerMonthWithRateFactorTotal += empDetail.ApprovedHoursPerMonthWithRateFactorTotal;
|
|
teamDetail.ApprovedHoursPerMonthWithRateFactor += empDetail.ApprovedHoursPerMonthWithRateFactor;
|
|
|
|
foreach (var scd in empDetail.SupportConceptDetailList)
|
|
{
|
|
teamDetail.SupportConceptDetailList.Add(scd);
|
|
}
|
|
|
|
}
|
|
if (teamDetail.ApprovedHoursPerWeek != 0)
|
|
teamDetail.RelationIstSoll = (teamDetail.DirectIst / teamDetail.ApprovedHoursPerWeek) * 100m;
|
|
|
|
if (teamDetail.DirectIst + teamDetail.MittelbarIst != 0)
|
|
teamDetail.RelationDirectToMittelbar = (teamDetail.DirectIst / (teamDetail.DirectIst + teamDetail.MittelbarIst)) * 100;
|
|
|
|
teamDetail.SupportConceptDetailList.Sort((a, b) =>
|
|
{
|
|
if (a.Customer == null)
|
|
return 1;
|
|
if (b.Customer == null)
|
|
return -1;
|
|
return (a.Customer.Person.LastName + ", " + a.Customer.Person.FirstName).CompareTo(
|
|
b.Customer.Person.LastName + ", " + b.Customer.Person.FirstName);
|
|
});
|
|
}
|
|
}
|
|
|
|
public virtual void CreateEmployeeDetails(MitarbeiterauslastungRO ro)
|
|
{
|
|
foreach (var empDetail in ro.EmployeeDetailList)
|
|
{
|
|
if (empDetail.Employee != null)
|
|
{
|
|
CreateSupportConceptsForEmployee(ro, empDetail);
|
|
}
|
|
else if (empDetail.Customer != null)
|
|
{
|
|
CreateSupportConceptsForCustomer(ro, empDetail);
|
|
}
|
|
if (CreateIst())
|
|
{
|
|
CreateServiceRecordDetails(ro, empDetail);
|
|
}
|
|
empDetail.SupportConceptDetailList.Sort((a, b) =>
|
|
{
|
|
if (a.Customer == null)
|
|
return 1;
|
|
if (b.Customer == null)
|
|
return -1;
|
|
return (a.Customer.Person.LastName + ", " + a.Customer.Person.FirstName).CompareTo(
|
|
b.Customer.Person.LastName + ", " + b.Customer.Person.FirstName);
|
|
});
|
|
}
|
|
}
|
|
|
|
public virtual bool CreateIst()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private void CreateSupportConceptsForCustomer(MitarbeiterauslastungRO ro, MitarbeiterauslastungRO.EmployeeDetail empDetail)
|
|
{
|
|
var span = new DateTimeSpan();
|
|
span.StartDateTime = ro.ReportStartDate;
|
|
span.EndDateTime = ro.ReportEndDate;
|
|
//supportconcepts by SupportConceptApprovalPeriodOid
|
|
Dictionary<long, MitarbeiterauslastungRO.SupportConceptDetail> supportConceptByScapDict = new Dictionary<long, MitarbeiterauslastungRO.SupportConceptDetail>();
|
|
|
|
foreach (var sc in empDetail.Customer.SupportConcepts)
|
|
{
|
|
if (sc.IsActive != ActivationTypeId.Deleted && sc.CostBearer2SupportConceptList != null)
|
|
{
|
|
foreach (CostBearer2SupportConcept c2s in sc.CostBearer2SupportConceptList)
|
|
{
|
|
foreach (var scap in c2s.ApprovalPeriodList)
|
|
{
|
|
//scDC.ApprovedHoursPerWeek -= stundenVerbraucht;
|
|
//scDC.ApprovedHoursPerWeekWithRateFactor -= stundenVerbraucht;
|
|
if (!supportConceptByScapDict.ContainsKey(scap.Oid.Value))
|
|
{
|
|
MitarbeiterauslastungRO.SupportConceptDetail scDc = GetOrCreateSupportConceptDetail(null, sc.Customer, scap, c2s, ro.ReportStartDate, ro.ReportEndDate, null, false);
|
|
if (scDc != null)
|
|
{
|
|
if (!CheckIfApprovedGreaterZero() || scDc.ApprovedHoursPerWeek > 0 || scDc.ApprovedHoursPerWeekWithRateFactor > 0)
|
|
{
|
|
empDetail.SupportConceptDetailList.Add(scDc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CreateSupportConceptsForEmployee(MitarbeiterauslastungRO ro, MitarbeiterauslastungRO.EmployeeDetail empDetail)
|
|
{
|
|
var emp = empDetail.Employee;
|
|
DateTime start = ro.ReportStartDate;
|
|
Contract contract = emp.GetValidContractForDate(ro.ReportStartDate);
|
|
while (contract == null && start < ro.ReportEndDate)
|
|
{
|
|
start = start.AddDays(1);
|
|
contract = emp.GetValidContractForDate(start);
|
|
}
|
|
|
|
if (contract != null)
|
|
{
|
|
empDetail.WeeklyTotalHoursByContract = contract.WeeklyTotalHours ?? 0;
|
|
empDetail.FLSTotalHoursByContract = contract.WeeklyFLS ?? 0;
|
|
empDetail.MonthlyTotalHoursByContract = contract.MonthlyTotalHours ?? empDetail.WeeklyTotalHoursByContract * 52 /12;
|
|
empDetail.FLSTotalMonthlyHoursByContract = contract.MonthlyFLS ?? empDetail.FLSTotalHoursByContract * 52 / 12;
|
|
}
|
|
|
|
empDetail.AbsenceTimeString = "";
|
|
if (emp.AbsenceTimes != null)
|
|
{
|
|
var sb = new StringBuilder();
|
|
var count = 1;
|
|
foreach (var at in emp.AbsenceTimes)
|
|
{
|
|
if (at.AbsenceSpan != null)
|
|
{
|
|
bool cont = true;
|
|
if (at.Start != null && at.Start >= ro.ReportEndDate)
|
|
{
|
|
cont = false;
|
|
}
|
|
if (cont && at.End != null && at.End < ro.ReportStartDate)
|
|
{
|
|
cont = false;
|
|
}
|
|
if (cont)
|
|
{
|
|
if (sb.Length > 0)
|
|
{
|
|
sb.Append(", ");
|
|
}
|
|
|
|
if (at.Start.HasValue)
|
|
{
|
|
sb.Append(string.Format("{0:00}", at.Start.Value.Day));
|
|
sb.Append(".");
|
|
sb.Append(string.Format("{0:00}", at.Start.Value.Month));
|
|
sb.Append(".");
|
|
sb.Append(at.Start.Value.Year.ToString().Substring(2));
|
|
|
|
if (at.End.HasValue)
|
|
{
|
|
sb.Append(" - ");
|
|
sb.Append(string.Format("{0:00}", at.End.Value.Day));
|
|
sb.Append(".");
|
|
sb.Append(string.Format("{0:00}", at.End.Value.Month));
|
|
sb.Append(".");
|
|
sb.Append(at.End.Value.Year.ToString().Substring(2));
|
|
}
|
|
}
|
|
sb.Append(" ");
|
|
sb.Append(at.AbsenceReason.Description);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
if (sb.Length > 0)
|
|
{
|
|
empDetail.AbsenceTimeString = "Abwesenheiten: " + sb.ToString();
|
|
}
|
|
}
|
|
|
|
Dictionary<long, MitarbeiterauslastungRO.SupportConceptDetail> supportConceptByScapDict = new Dictionary<long, MitarbeiterauslastungRO.SupportConceptDetail>();
|
|
var anteile = CreateAuslastungAnteilig(emp);
|
|
|
|
foreach (var anteil in anteile)
|
|
{
|
|
var scap = anteil.SupportConceptApprovalPeriod;
|
|
var cb2sc = anteil.CostBearer2SupportConcept;
|
|
var sc = cb2sc.SupportConcept;
|
|
if (sc.IsActive != ActivationTypeId.Deleted && !supportConceptByScapDict.ContainsKey(scap.Oid.Value))
|
|
{
|
|
MitarbeiterauslastungRO.SupportConceptDetail scDc = GetOrCreateSupportConceptDetail(emp, sc.Customer, scap, cb2sc, ro.ReportStartDate, ro.ReportEndDate, anteil, false);
|
|
if (scDc != null)
|
|
{
|
|
supportConceptByScapDict.Add(scap.Oid.Value, scDc);
|
|
|
|
empDetail.SupportConceptDetailList.Add(scDc);
|
|
}
|
|
}
|
|
}
|
|
if (emp.Employee2CustomerList != null)
|
|
{
|
|
foreach (Employee2Customer e2c in emp.Employee2CustomerList)
|
|
{
|
|
bool isMainAttendant = false;
|
|
if (e2c.ValueList.Count > 0)
|
|
{
|
|
SystemEntryID? id = e2c.ValueList[0].Entry.SystemEntryID;
|
|
if (id.HasValue && id.Value == SystemEntryID.EmployeeRoleMainAttendant)
|
|
isMainAttendant = true;
|
|
}
|
|
if (isMainAttendant && e2c.Customer != null && (!e2c.StartDate.HasValue || e2c.StartDate.Value.Date < ro.ReportEndDate.Date) && (!e2c.EndDate.HasValue || e2c.EndDate.Value.Date >= ro.ReportStartDate))
|
|
{
|
|
if (e2c.Customer.IsActive != ActivationTypeId.Deleted && e2c.Customer.SupportConcepts != null)
|
|
{
|
|
foreach (SupportConcept sc in e2c.Customer.SupportConcepts)
|
|
{
|
|
if (sc.IsActive != ActivationTypeId.Deleted && sc.CostBearer2SupportConceptList != null)
|
|
{
|
|
foreach (CostBearer2SupportConcept c2s in sc.CostBearer2SupportConceptList)
|
|
{
|
|
foreach (var scap in c2s.ApprovalPeriodList)
|
|
{
|
|
//scDC.ApprovedHoursPerWeek -= stundenVerbraucht;
|
|
//scDC.ApprovedHoursPerWeekWithRateFactor -= stundenVerbraucht;
|
|
|
|
if (!supportConceptByScapDict.ContainsKey(scap.Oid.Value))
|
|
{
|
|
MitarbeiterauslastungRO.SupportConceptDetail scDc = GetOrCreateSupportConceptDetail(emp, e2c.Customer, scap, c2s, ro.ReportStartDate, ro.ReportEndDate, null, true);
|
|
if (scDc != null)
|
|
{
|
|
if (scDc.ApprovedHoursPerWeek > 0.00001m || scDc.ApprovedHoursPerWeekWithRateFactor > 0.00001m || !CheckIfApprovedGreaterZero())
|
|
{
|
|
empDetail.SupportConceptDetailList.Add(scDc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual bool CheckIfApprovedGreaterZero()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
protected virtual MitarbeiterauslastungRO.SupportConceptDetail GetOrCreateSupportConceptDetail(Employee emp, Customer customer, SupportConceptApprovalPeriod scap, CostBearer2SupportConcept cb2sc, DateTime start, DateTime ende, AuslastungBerechnungHelper anteil, bool ausHauptbetreuung)
|
|
{
|
|
bool inTimeRange = true;
|
|
var realEnd = scap.EndDate;
|
|
|
|
if (customer.Person.LastName.StartsWith("Bosch"))
|
|
{
|
|
int test = 0;
|
|
}
|
|
//Prüfe ob vorher abgemeldet
|
|
if (customer.TerminationDate.HasValue && customer.TerminationDate.Value < realEnd)
|
|
{
|
|
realEnd = customer.TerminationDate.Value;
|
|
}
|
|
|
|
if (scap.StartDate.HasValue && realEnd.HasValue)
|
|
{
|
|
//if (scap.StartDate >= ende || realEnd < ende.AddDays(-1))
|
|
if (scap.StartDate >= ende || realEnd < start)
|
|
{
|
|
inTimeRange = false;
|
|
}
|
|
}
|
|
|
|
if (inTimeRange)
|
|
{
|
|
String key = "";
|
|
if (emp != null)
|
|
{
|
|
key = String.Format("e{0}_{1}", emp.Oid.Value, scap.Oid.Value);
|
|
}
|
|
else
|
|
{
|
|
if (customer.Oid.Value == 277)
|
|
{
|
|
int test = 0;
|
|
}
|
|
key = String.Format("c{0}_{1}", customer.Oid.Value, scap.Oid.Value);
|
|
}
|
|
if (betreuungDict.ContainsKey(key))
|
|
{
|
|
return betreuungDict[key];
|
|
}
|
|
var scDC = new MitarbeiterauslastungRO.SupportConceptDetail();
|
|
scDC.Customer = customer;
|
|
if (customer.Person.FirstName == "Leo")
|
|
{
|
|
int test = 0;
|
|
}
|
|
scDC.SupportConceptApprovalPeriod = scap;
|
|
scDC.CostBearer2SupportConcept = DAOFactory.GenericDAO.Unproxy(cb2sc);
|
|
|
|
var EndDate = DateTime.Now;
|
|
if (ende < EndDate)
|
|
{
|
|
EndDate = ende; // ende.AddMilliseconds(-1);
|
|
}
|
|
// "Frei pro Woche" aus der Zeiterfassungsstatistik hinzufügen
|
|
var stats = new ServiceRecordStatisticFactory().CreateSupportConceptStatisticsImpl(cb2sc.Oid.Value, EndDate);
|
|
scDC.FreiProWocheDurchschnittUberGesamtZeitraum = Math.Round(stats.MinutesFreePerWeekAverage / 60, 2, MidpointRounding.AwayFromZero);
|
|
|
|
if (stats.PeriodStatistics != null && stats.PeriodStatistics.Any(s => s.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid == scap.Oid))
|
|
{
|
|
var stat = stats.PeriodStatistics.First(s => s.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid == scap.Oid);
|
|
scDC.FreiProWoche = Math.Round(stat.MinutesFreePerWeekStatisticDate / 60, 2, MidpointRounding.AwayFromZero);
|
|
scDC.FreiProMonat = Math.Round(stat.MinutesFreePerMonthStatisticDate / 60, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
// Prozentwert aus der Bewilligung einbeziehen
|
|
if (anteil != null)
|
|
{
|
|
if (!anteil.IsBetreuungsschluesselAbsolut)
|
|
{
|
|
scDC.FreiProWoche *= anteil.AnteilAnBetreuung / 100;
|
|
scDC.FreiProMonat *= anteil.AnteilAnBetreuung / 100;
|
|
scDC.FreiProWocheDurchschnittUberGesamtZeitraum *= anteil.AnteilAnBetreuung / 100;
|
|
}
|
|
// Minutenwert aus der Bewilligung einbeziehen
|
|
else
|
|
{
|
|
var minProWoche = stats.PeriodStatistics.Sum(s => s.MinutesApprovedPerWeek); // MinutesApprovedPerWeek ist 0, ich muss durch die einzelnen stats laufen uns selber hochrechnen
|
|
if (minProWoche != 0)
|
|
{
|
|
scDC.FreiProWoche *= anteil.AnteilAnBetreuung / minProWoche;
|
|
scDC.FreiProMonat *= anteil.AnteilAnBetreuung / minProWoche;
|
|
scDC.FreiProWocheDurchschnittUberGesamtZeitraum *= anteil.AnteilAnBetreuung / minProWoche;
|
|
}
|
|
}
|
|
}
|
|
DateTime end = ende;
|
|
if (realEnd.HasValue && realEnd.Value < end)
|
|
{
|
|
end = realEnd.Value;
|
|
}
|
|
CalculateSoll(scDC, end);
|
|
if (ausHauptbetreuung)
|
|
{
|
|
var anteileAndererEmps = CreateAuslastungAnteilig(scap);
|
|
foreach (var ant in anteileAndererEmps)
|
|
{
|
|
var scDcAnteil =
|
|
GetOrCreateSupportConceptDetail(ant.Employee, customer, scap, cb2sc, start, ende, ant, false);
|
|
|
|
if (scDcAnteil != null)
|
|
{
|
|
scDC.ApprovedHoursPerWeek -= scDcAnteil.ApprovedHoursPerWeek;
|
|
scDC.ApprovedHoursPerWeekWithRateFactor -= scDcAnteil.ApprovedHoursPerWeekWithRateFactor;
|
|
scDC.ApprovedHoursPerMonth -= scDcAnteil.ApprovedHoursPerMonth;
|
|
scDC.ApprovedHoursPerMonthWithRateFactor -= scDcAnteil.ApprovedHoursPerMonthWithRateFactor;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ApplyBetreuungsschluessel(scDC, anteil);
|
|
}
|
|
|
|
if (betreuungDict.ContainsKey(key))
|
|
{
|
|
int test = 0;
|
|
}
|
|
else
|
|
{
|
|
betreuungDict.Add(key, scDC);
|
|
}
|
|
return scDC;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public virtual void ApplyBetreuungsschluessel(MitarbeiterauslastungRO.SupportConceptDetail scDc, AuslastungBerechnungHelper anteil)
|
|
{
|
|
if (anteil != null)
|
|
{
|
|
if (!anteil.IsBetreuungsschluesselAbsolut)
|
|
{
|
|
if (anteil.AnteilAnBetreuung == 33)
|
|
{
|
|
anteil.AnteilAnBetreuung = 100m / 3m;
|
|
}
|
|
else if (anteil.AnteilAnBetreuung == 67)
|
|
{
|
|
anteil.AnteilAnBetreuung = (100m / 3m) * 2;
|
|
}
|
|
|
|
scDc.ApprovedHoursPerWeek *= (anteil.AnteilAnBetreuung / 100);
|
|
scDc.ApprovedHoursPerWeekWithRateFactor *= (anteil.AnteilAnBetreuung / 100);
|
|
scDc.ApprovedHoursPerMonth *= (anteil.AnteilAnBetreuung / 100);
|
|
scDc.ApprovedHoursPerMonthWithRateFactor *= (anteil.AnteilAnBetreuung / 100);
|
|
}
|
|
else
|
|
{
|
|
if (scDc.ApprovedHoursPerWeekWithRateFactor > 0)
|
|
{
|
|
scDc.ApprovedHoursPerWeek = (anteil.AnteilAnBetreuung / 60) * (scDc.ApprovedHoursPerWeek / scDc.ApprovedHoursPerWeekWithRateFactor);
|
|
}
|
|
if (scDc.ApprovedHoursPerMonthWithRateFactor > 0)
|
|
{
|
|
scDc.ApprovedHoursPerMonth = (anteil.AnteilAnBetreuung / 60) * (scDc.ApprovedHoursPerMonth / scDc.ApprovedHoursPerMonthWithRateFactor);
|
|
}
|
|
scDc.ApprovedHoursPerWeekWithRateFactor = anteil.AnteilAnBetreuung / 60;
|
|
scDc.ApprovedHoursPerMonthWithRateFactor = anteil.AnteilAnBetreuung / 60;
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual IList<AuslastungBerechnungHelper> CreateAuslastungAnteilig(Employee emp)
|
|
{
|
|
var anteile = new List<AuslastungBerechnungHelper>();
|
|
var sp2eList = DAOFactory.SearchDAO.FindSupportConceptApprovalPeriod2Employees(emp);
|
|
foreach (var sp2e in sp2eList)
|
|
{
|
|
var helper = new AuslastungBerechnungHelper();
|
|
helper.SupportConceptApprovalPeriod = DAOFactory.GenericDAO.Unproxy(sp2e.SupportConceptApprovalPeriod);
|
|
helper.CostBearer2SupportConcept = DAOFactory.GenericDAO.Unproxy(helper.SupportConceptApprovalPeriod.CostBearer2SupportConcept);
|
|
helper.AnteilAnBetreuung = sp2e.Betreuungsschluessel;
|
|
helper.IsBetreuungsschluesselAbsolut = sp2e.IsAbsolut;
|
|
|
|
anteile.Add(helper);
|
|
}
|
|
return anteile;
|
|
}
|
|
|
|
public virtual IList<AuslastungBerechnungHelper> CreateAuslastungAnteilig(SupportConceptApprovalPeriod scap)
|
|
{
|
|
var anteile = new List<AuslastungBerechnungHelper>();
|
|
var sp2eList = DAOFactory.SearchDAO.FindSupportConceptApprovalPeriod2Employees(scap);
|
|
|
|
foreach (var sp2e in sp2eList)
|
|
{
|
|
var helper = new AuslastungBerechnungHelper();
|
|
|
|
helper.Employee = DAOFactory.GenericDAO.Unproxy(sp2e.Employee);
|
|
helper.SupportConceptApprovalPeriod = DAOFactory.GenericDAO.Unproxy(sp2e.SupportConceptApprovalPeriod);
|
|
helper.CostBearer2SupportConcept = DAOFactory.GenericDAO.Unproxy(helper.SupportConceptApprovalPeriod.CostBearer2SupportConcept);
|
|
helper.AnteilAnBetreuung = sp2e.Betreuungsschluessel;
|
|
helper.IsBetreuungsschluesselAbsolut = sp2e.IsAbsolut;
|
|
|
|
anteile.Add(helper);
|
|
}
|
|
|
|
return anteile;
|
|
}
|
|
|
|
public virtual void CreateServiceRecordDetails(MitarbeiterauslastungRO ro, MitarbeiterauslastungRO.EmployeeDetail empDetail)
|
|
{
|
|
IList<ServiceRecord> records = null;
|
|
var span = new DateTimeSpan();
|
|
span.StartDateTime = ro.ReportStartDate;
|
|
span.EndDateTime = ro.ReportEndDate.AddTicks(-1);
|
|
if (empDetail.Employee != null)
|
|
{
|
|
records = DAOFactory.SearchDAO.FindEmployeeServiceRecords(empDetail.Employee.Oid.Value, span, null, null);
|
|
}
|
|
else if (empDetail.Customer != null)
|
|
{
|
|
records = DAOFactory.SearchDAO.FindCustomerServiceRecords(empDetail.Customer.Oid.Value, span, null, null, false);
|
|
}
|
|
|
|
foreach (ServiceRecord sr in records)
|
|
{
|
|
if (sr.Start >= ro.ReportStartDate && sr.Start.Value < ro.ReportEndDate)
|
|
{
|
|
var scd = GetSupportConceptDetailForServiceRecord(empDetail, sr);
|
|
|
|
if (scd != null)
|
|
{
|
|
if (empDetail.Employee != null)
|
|
{
|
|
if (sr.EmployeeOid.HasValue && sr.EmployeeOid == empDetail.Employee.Oid)
|
|
{
|
|
AddServiceRecord(ro, scd, sr);
|
|
}
|
|
}
|
|
else if (empDetail.Customer != null)
|
|
{
|
|
AddServiceRecord(ro, scd, sr);
|
|
|
|
}
|
|
if (sr.GroupOid != null)
|
|
{
|
|
//groupBookingDict.Add(sr.GroupOid.Value, sr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// foreach (var scd in empDetail.SupportConceptDetailList)
|
|
//{
|
|
// if (scd.CostBearer2SupportConcept != null)
|
|
// {
|
|
|
|
// Dictionary<long, bool> serviceRecordsProcessed = new Dictionary<long, bool>();
|
|
|
|
|
|
// Dictionary<long, ServiceRecord> groupBookingDict = new Dictionary<long, ServiceRecord>();
|
|
// foreach (ServiceRecord sr in records)
|
|
// {
|
|
// if (!serviceRecordsProcessed.ContainsKey(sr.Oid.Value) && sr.Start >= ro.ReportStartDate &&
|
|
// sr.Start.Value < ro.ReportEndDate)
|
|
// {
|
|
// if (empDetail.Employee != null)
|
|
// {
|
|
// if (sr.EmployeeOid.HasValue && sr.EmployeeOid == empDetail.Employee.Oid)
|
|
// {
|
|
// AddServiceRecord(ro, scd, sr);
|
|
|
|
// serviceRecordsProcessed.Add(sr.Oid.Value, true);
|
|
// }
|
|
// }
|
|
// else if (empDetail.Customer != null)
|
|
// {
|
|
// AddServiceRecord(ro, scd, sr);
|
|
|
|
// serviceRecordsProcessed.Add(sr.Oid.Value, true);
|
|
|
|
// }
|
|
|
|
|
|
// if (sr.GroupOid != null)
|
|
// {
|
|
// //groupBookingDict.Add(sr.GroupOid.Value, sr);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//var emprecords = DAOFactory.SearchDAO.FindEmployeeServiceRecordsWithoutCustomer(empDetail.Employee.Oid.Value);
|
|
//foreach (var sr in emprecords)
|
|
//{
|
|
// empDetail.MinutesOfOtherActivities += sr.RoundedDuration;
|
|
//}
|
|
}
|
|
|
|
public virtual MitarbeiterauslastungRO.SupportConceptDetail GetSupportConceptDetailForServiceRecord(MitarbeiterauslastungRO.EmployeeDetail empDetail, ServiceRecord sr)
|
|
{
|
|
if (sr.CostBearer2SupportConcept == null)
|
|
{
|
|
foreach (var scdi in empDetail.SupportConceptDetailList)
|
|
{
|
|
if (scdi.SupportConceptApprovalPeriod == null)
|
|
{
|
|
return scdi;
|
|
}
|
|
}
|
|
}
|
|
|
|
SupportConceptApprovalPeriod scap = GetSupportConceptApprovalPeriodForServiceRecord(sr);
|
|
if (scap != null)
|
|
{
|
|
foreach (var scdi in empDetail.SupportConceptDetailList)
|
|
{
|
|
if (scdi.SupportConceptApprovalPeriod != null && scdi.SupportConceptApprovalPeriod.Oid == scap.Oid)
|
|
{
|
|
return scdi;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sr.ServiceDescription != null &&
|
|
sr.ServiceDescription.ServiceCategory != null &&
|
|
sr.ServiceDescription.ServiceCategory.IsBillable)
|
|
{
|
|
var scd = new MitarbeiterauslastungRO.SupportConceptDetail();
|
|
scd.Customer = sr.Customer;
|
|
scd.SupportConceptApprovalPeriod = scap;
|
|
scd.CostBearer2SupportConcept = DAOFactory.GenericDAO.Unproxy(sr.CostBearer2SupportConcept);
|
|
|
|
if (scd.SupportConceptApprovalPeriod != null)
|
|
{
|
|
scd.StartDate = scd.SupportConceptApprovalPeriod.StartDate;
|
|
scd.EndDate = scd.SupportConceptApprovalPeriod.EndDate;
|
|
}
|
|
else if (scd.CostBearer2SupportConcept != null)
|
|
{
|
|
scd.StartDate = scd.CostBearer2SupportConcept.StartDate;
|
|
scd.EndDate = scd.CostBearer2SupportConcept.EndDate;
|
|
}
|
|
empDetail.SupportConceptDetailList.Add(scd);
|
|
|
|
return scd;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public virtual SupportConceptApprovalPeriod GetSupportConceptApprovalPeriodForServiceRecord(ServiceRecord sr)
|
|
{
|
|
SupportConceptApprovalPeriod scapOhneCat = null;
|
|
if (sr.CostBearer2SupportConcept != null)
|
|
{
|
|
foreach (var scap in sr.CostBearer2SupportConcept.ApprovalPeriodList)
|
|
{
|
|
DateTime start = DateTime.MinValue;
|
|
DateTime end = DateTime.MaxValue;
|
|
|
|
if (scap.StartDate.HasValue)
|
|
start = scap.StartDate.Value;
|
|
if (scap.EndDate.HasValue && scap.EndDate.Value.Date < end)
|
|
end = scap.EndDate.Value.Date.AddDays(1);
|
|
|
|
if (sr.Start >= start && sr.End < end)
|
|
{
|
|
if (scap.ServiceCategory != null && scap.ServiceCategory.Oid == sr.ServiceDescription.ServiceCategory.Oid)
|
|
return scap;
|
|
if (scap.ServiceCategory == null)
|
|
{
|
|
scapOhneCat = scap;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return scapOhneCat;
|
|
}
|
|
|
|
public virtual void AddServiceRecord(MitarbeiterauslastungRO ro, MitarbeiterauslastungRO.SupportConceptDetail scDC, ServiceRecord sr)
|
|
{
|
|
var minutes = GetBillableDurationInMinutes(sr);
|
|
if (sr.ServiceDescription != null && sr.ServiceDescription.ServiceCategory != null && sr.ServiceDescription.ServiceCategory.IsBillable)
|
|
{
|
|
scDC.DirectIst += minutes;
|
|
AddToIstForKw(minutes, sr.Start.Value, ro.ReportStartDate, ro.ReportEndDate, scDC);
|
|
}
|
|
else
|
|
{
|
|
scDC.MittelbarIst += minutes;
|
|
}
|
|
}
|
|
|
|
private void AddToIstForKw(decimal minutes, DateTime datum, DateTime reportStart, DateTime reportEnd, MitarbeiterauslastungRO.SupportConceptDetail scDC)
|
|
{
|
|
DateTimeSpan kw1 = new DateTimeSpan();
|
|
kw1.StartDate = reportStart;
|
|
|
|
DateTime start = reportStart;
|
|
while (start.DayOfWeek != DayOfWeek.Sunday)
|
|
{
|
|
start = start.AddDays(1);
|
|
}
|
|
kw1.EndDate = start;
|
|
|
|
DateTimeSpan kw2 = new DateTimeSpan();
|
|
kw2.StartDate = kw1.EndDate.AddDays(1);
|
|
kw2.EndDate = kw2.StartDate.AddDays(6);
|
|
|
|
DateTimeSpan kw3 = new DateTimeSpan();
|
|
kw3.StartDate = kw2.EndDate.AddDays(1);
|
|
kw3.EndDate = kw3.StartDate.AddDays(6);
|
|
|
|
DateTimeSpan kw4 = new DateTimeSpan();
|
|
kw4.StartDate = kw3.EndDate.AddDays(1);
|
|
kw4.EndDate = kw4.StartDate.AddDays(6);
|
|
|
|
DateTimeSpan kw5 = new DateTimeSpan();
|
|
kw5.StartDate = kw4.EndDate.AddDays(1);
|
|
kw5.EndDate = kw5.StartDate.AddDays(6);
|
|
|
|
DateTimeSpan kw6 = new DateTimeSpan();
|
|
kw6.StartDate = kw5.EndDate.AddDays(1);
|
|
kw6.EndDate = kw6.StartDate.AddDays(6);
|
|
if (reportEnd <= kw5.EndDate)
|
|
{
|
|
kw5.EndDate = reportEnd.AddDays(-1);
|
|
}
|
|
if (reportEnd <= kw6.EndDate)
|
|
{
|
|
kw6.EndDate = reportEnd.AddDays(-1);
|
|
}
|
|
|
|
if (datum >= kw1.StartDate && datum.Date <= kw1.EndDate)
|
|
{
|
|
scDC.IstKw1 += minutes;
|
|
}
|
|
else if (datum >= kw2.StartDate && datum.Date <= kw2.EndDate)
|
|
{
|
|
scDC.IstKw2 += minutes;
|
|
}
|
|
else if (datum >= kw3.StartDate && datum.Date <= kw3.EndDate)
|
|
{
|
|
scDC.IstKw3 += minutes;
|
|
}
|
|
else if (datum >= kw4.StartDate && datum.Date <= kw4.EndDate && datum < reportEnd)
|
|
{
|
|
scDC.IstKw4 += minutes;
|
|
}
|
|
else if (datum >= kw5.StartDate && datum.Date <= kw5.EndDate && datum < reportEnd)
|
|
{
|
|
scDC.IstKw5 += minutes;
|
|
}
|
|
else if (datum >= kw6.StartDate && datum.Date <= kw6.EndDate && datum < reportEnd)
|
|
{
|
|
scDC.IstKw6 += minutes;
|
|
}
|
|
}
|
|
|
|
public virtual void AddServiceRecord(MitarbeiterauslastungRO.SupportConceptDetail scDC, ServiceRecord sr)
|
|
{
|
|
var minutes = GetBillableDurationInMinutes(sr);
|
|
|
|
if (sr.ServiceDescription != null && sr.ServiceDescription.ServiceCategory != null && sr.ServiceDescription.ServiceCategory.IsBillable)
|
|
{
|
|
scDC.DirectIst += minutes;
|
|
}
|
|
else
|
|
{
|
|
scDC.MittelbarIst += minutes;
|
|
}
|
|
}
|
|
|
|
public virtual decimal GetBillableDurationInMinutes(ServiceRecord record)
|
|
{
|
|
decimal rdMinutes = record.RoundedDuration;
|
|
var prozent = record.ServiceDescription.ServiceCategory.ProzentAbrechnung;
|
|
if (record.ServiceDescription.ProzentAbrechnung.HasValue)
|
|
{
|
|
prozent = record.ServiceDescription.ProzentAbrechnung.Value;
|
|
}
|
|
rdMinutes *= prozent / 100;
|
|
|
|
if (record.GroupEmployeeCount.HasValue)
|
|
{
|
|
rdMinutes /= record.GroupEmployeeCount.Value;
|
|
}
|
|
return rdMinutes;
|
|
}
|
|
|
|
public virtual void CalculateSoll(MitarbeiterauslastungRO.SupportConceptDetail scDC, DateTime date)
|
|
{
|
|
if (scDC.CostBearer2SupportConcept != null && scDC.SupportConceptApprovalPeriod != null)
|
|
{
|
|
var calc = PluginLoader.FindClass<Calculations>(scDC.CostBearer2SupportConcept.CostBearer.ID) ?? Calculations.GetInstance(scDC.CostBearer2SupportConcept.CostBearer.ID);
|
|
var cb2scDc = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(scDC.CostBearer2SupportConcept);
|
|
var scapDc = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(scDC.SupportConceptApprovalPeriod);
|
|
var bewilligt = calc.GetApprovedHoursPerWeek(scapDc, cb2scDc.CostBearer.CostRatePeriods) ?? 0m;
|
|
|
|
scDC.ApprovedHoursPerWeek = calc.ApplyIsCalculationWithFactor(cb2scDc, bewilligt) ?? 0m;
|
|
scDC.ApprovedHoursPerWeekTotal = scDC.ApprovedHoursPerWeek;
|
|
scDC.ApprovedHoursPerWeekWithRateFactor = bewilligt;
|
|
scDC.ApprovedHoursPerWeekWithRateFactorTotal = scDC.ApprovedHoursPerWeekWithRateFactor;
|
|
|
|
decimal bewilligtMonth = 0;
|
|
if (scapDc.ApprovedBEInterval.HasValue && scapDc.ApprovedBEPerInterval.HasValue && scapDc.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Monthly)
|
|
{
|
|
bewilligtMonth = scapDc.ApprovedBEPerInterval.Value;
|
|
scDC.ApprovedHoursPerMonth = calc.ApplyIsCalculationWithFactor(cb2scDc, bewilligtMonth) ?? 0m;
|
|
scDC.ApprovedHoursPerMonthTotal = scDC.ApprovedHoursPerMonth;
|
|
scDC.ApprovedHoursPerMonthWithRateFactor = bewilligtMonth;
|
|
scDC.ApprovedHoursPerMonthWithRateFactorTotal = scDC.ApprovedHoursPerMonthWithRateFactor;
|
|
}
|
|
else
|
|
{
|
|
scDC.ApprovedHoursPerMonth = scDC.ApprovedHoursPerWeek * 4.33m;
|
|
scDC.ApprovedHoursPerMonthTotal = scDC.ApprovedHoursPerWeekTotal * 4.33m;
|
|
scDC.ApprovedHoursPerMonthWithRateFactor = scDC.ApprovedHoursPerWeekWithRateFactor * 4.33m;
|
|
scDC.ApprovedHoursPerMonthWithRateFactorTotal = scDC.ApprovedHoursPerWeekWithRateFactorTotal * 4.33m;
|
|
}
|
|
scDC.StartDate = scDC.SupportConceptApprovalPeriod.StartDate;
|
|
scDC.EndDate = scDC.SupportConceptApprovalPeriod.EndDate;
|
|
scDC.WeekCountUntilNow = calc.GetDurationInWeeksTillNow(cb2scDc, date) ?? 0;
|
|
}
|
|
else if (scDC.CostBearer2SupportConcept != null && scDC.SupportConceptApprovalPeriod == null)
|
|
{
|
|
var calc = PluginLoader.FindClass<Calculations>(scDC.CostBearer2SupportConcept.CostBearer.ID) ?? Calculations.GetInstance(scDC.CostBearer2SupportConcept.CostBearer.ID);
|
|
var cb2scDc = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(scDC.CostBearer2SupportConcept);
|
|
|
|
scDC.ApprovedHoursPerWeek = calc.GetApprovedHoursPerWeek(cb2scDc, date) ?? 0m;
|
|
scDC.ApprovedHoursPerWeekTotal = scDC.ApprovedHoursPerWeek;
|
|
scDC.ApprovedHoursPerWeekWithRateFactor = calc.GetApprovedHoursPerWeek(cb2scDc, date, false) ?? 0m;
|
|
scDC.ApprovedHoursPerWeekWithRateFactorTotal = scDC.ApprovedHoursPerWeekWithRateFactor;
|
|
|
|
if (cb2scDc.EndDate.HasValue && cb2scDc.StartDate.HasValue)
|
|
{
|
|
var months = calc.GetTotalMonths(cb2scDc.StartDate.Value, cb2scDc.EndDate.Value);
|
|
var bewGes = calc.GetApprovedHoursForPeriod(cb2scDc, cb2scDc.StartDate.Value, cb2scDc.EndDate.Value);
|
|
scDC.ApprovedHoursPerMonth = bewGes / months;
|
|
scDC.ApprovedHoursPerMonthTotal = scDC.ApprovedHoursPerMonth;
|
|
scDC.ApprovedHoursPerMonthWithRateFactor = (decimal)calc.ApplyIsCalculationWithFactor(cb2scDc, scDC.ApprovedHoursPerMonth);
|
|
scDC.ApprovedHoursPerMonthWithRateFactorTotal = scDC.ApprovedHoursPerMonthWithRateFactor;
|
|
}
|
|
|
|
scDC.StartDate = scDC.CostBearer2SupportConcept.StartDate;
|
|
scDC.EndDate = scDC.CostBearer2SupportConcept.EndDate;
|
|
scDC.WeekCountUntilNow = calc.GetDurationInWeeksTillNow(cb2scDc, date) ?? 0;
|
|
}
|
|
}
|
|
|
|
public Contract GetNextValidContractForDate(DateTime dt, Employee emp)
|
|
{
|
|
Contract contractNextToStartDate = emp.GetValidContractForDate(dt);
|
|
if (contractNextToStartDate == null)
|
|
{
|
|
DateTime minDate = DateTime.MinValue;
|
|
DateTime maxDate = DateTime.MaxValue;
|
|
|
|
foreach (var item in emp.Contracts)
|
|
{
|
|
if (item.EntryDate.HasValue && item.EntryDate.Value >= dt)
|
|
{
|
|
if (contractNextToStartDate == null || item.EntryDate.Value < contractNextToStartDate.EntryDate.Value)
|
|
{
|
|
contractNextToStartDate = item;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return contractNextToStartDate;
|
|
}
|
|
}
|
|
|
|
public class AuslastungBerechnungHelper
|
|
{
|
|
public Employee Employee { get; set; }
|
|
public SupportConceptApprovalPeriod SupportConceptApprovalPeriod { get; set; }
|
|
public CostBearer2SupportConcept CostBearer2SupportConcept { get; set; }
|
|
public decimal AnteilAnBetreuung { get; set; }
|
|
public bool IsBetreuungsschluesselAbsolut { get; set; }
|
|
}
|
|
}
|