MH: LebenshilfeStadeMID Ausnahmefall Pausen Timo
SupportOID=168937
This commit is contained in:
@@ -11,8 +11,10 @@ namespace LebenshilfeStadeMID
|
||||
public class CustomMitarbeiterstundenkontoBerechnung : MitarbeiterstundenkontoBerechnung
|
||||
{
|
||||
private const int ANZ_WOCHENTAGE = 5;
|
||||
private Dictionary<string, decimal> _SollStundenProTagDict = new Dictionary<string, decimal>(); //Speicher die Sollstunden aus den Betreuungszeiten des Kindes pro EmployeeOid und Tag (Key = {employee oid}_{datum])
|
||||
private Dictionary<string, decimal> _SollStundenProTagDict = new Dictionary<string, decimal>(); //Speicher die Sollstunden aus den Betreuungszeiten des Kindes pro EmployeeOid und Tag (Key = {employee oid}_{datum])
|
||||
private DateTime _BerichtsAnfang = DateTime.MinValue;
|
||||
// Claude: Sonderfall Timo Lafram – Cache CustomerOid -> ist dieser Klient (vermeidet wiederholtes Nachladen des Customers)
|
||||
private readonly Dictionary<long, bool> _IstTimoLaframCache = new Dictionary<long, bool>();
|
||||
|
||||
protected override void StarteBerechnung(DateTime berichtsAnfang, DateTime berichtsEnde, MitarbeiterstundenkontoRO.EmployeeDetail empDetail)
|
||||
{
|
||||
@@ -273,6 +275,106 @@ namespace LebenshilfeStadeMID
|
||||
|
||||
return dd;
|
||||
}
|
||||
|
||||
// Claude: Sonderfall Klient "Timo Lafram" – für zusammenhängende Arbeitsblöcke, die (auch) Zeit für diesen
|
||||
// Klienten enthalten, wird KEINE automatische Pause abgezogen. Alle übrigen Tage/Blöcke bleiben unverändert
|
||||
// (Standardverhalten wie bisher = SONST IMMER Pause).
|
||||
public override decimal CalculateBreakMinutesNeu(MitarbeiterstundenkontoRO.DayDetail dayDetail)
|
||||
{
|
||||
// Kein Timo-Lafram-Eintrag an diesem Tag -> unverändertes Standardverhalten
|
||||
if (dayDetail.ServiceRecords == null || !dayDetail.ServiceRecords.Any(IstTimoLaframRecord))
|
||||
{
|
||||
return base.CalculateBreakMinutesNeu(dayDetail);
|
||||
}
|
||||
|
||||
decimal addHours = 0;
|
||||
|
||||
if (dayDetail.ZusammenhaengendeZeitraeume != null && dayDetail.ZusammenhaengendeZeitraeume.Count > 0)
|
||||
{
|
||||
foreach (var span in dayDetail.ZusammenhaengendeZeitraeume)
|
||||
{
|
||||
// Blöcke mit Timo-Lafram-Zeit: keine automatische Pause abziehen
|
||||
if (SpanEnthaeltTimoLaframZeit(dayDetail, span.StartDateTime, span.EndDateTime))
|
||||
continue;
|
||||
|
||||
addHours -= BerechneGesetzlichePauseInMinuten(dayDetail, span.StartDateTime, span.EndDateTime) / 60;
|
||||
}
|
||||
|
||||
return addHours;
|
||||
}
|
||||
|
||||
// Fallback (keine ZusammenhaengendeZeitraeume) analog zum Standard, Timo-Lafram-Blöcke überspringen
|
||||
if (dayDetail.EndDateTime1.HasValue && dayDetail.StartDateTime1.HasValue
|
||||
&& !SpanEnthaeltTimoLaframZeit(dayDetail, dayDetail.StartDateTime1.Value, dayDetail.EndDateTime1.Value))
|
||||
{
|
||||
addHours -= BerechneGesetzlichePauseInMinuten(dayDetail, dayDetail.StartDateTime1.Value, dayDetail.EndDateTime1.Value) / 60;
|
||||
}
|
||||
if (dayDetail.EndDateTime2.HasValue && dayDetail.StartDateTime2.HasValue
|
||||
&& !SpanEnthaeltTimoLaframZeit(dayDetail, dayDetail.StartDateTime2.Value, dayDetail.EndDateTime2.Value))
|
||||
{
|
||||
addHours -= BerechneGesetzlichePauseInMinuten(dayDetail, dayDetail.StartDateTime2.Value, dayDetail.EndDateTime2.Value) / 60;
|
||||
}
|
||||
if (dayDetail.EndDateTime3.HasValue && dayDetail.StartDateTime3.HasValue
|
||||
&& !SpanEnthaeltTimoLaframZeit(dayDetail, dayDetail.StartDateTime3.Value, dayDetail.EndDateTime3.Value))
|
||||
{
|
||||
addHours -= BerechneGesetzlichePauseInMinuten(dayDetail, dayDetail.StartDateTime3.Value, dayDetail.EndDateTime3.Value) / 60;
|
||||
}
|
||||
if (dayDetail.EndDateTime4.HasValue && dayDetail.StartDateTime4.HasValue
|
||||
&& !SpanEnthaeltTimoLaframZeit(dayDetail, dayDetail.StartDateTime4.Value, dayDetail.EndDateTime4.Value))
|
||||
{
|
||||
addHours -= BerechneGesetzlichePauseInMinuten(dayDetail, dayDetail.StartDateTime4.Value, dayDetail.EndDateTime4.Value) / 60;
|
||||
}
|
||||
|
||||
return addHours;
|
||||
}
|
||||
|
||||
// Claude: Prüft, ob im angegebenen Zeitraum (zusammenhängender Arbeitsblock) ein ServiceRecord für den
|
||||
// Klienten "Timo Lafram" liegt. Die Blöcke werden aus den Startzeiten der Records gebildet, daher genügt
|
||||
// die Prüfung, ob der Start eines Timo-Records innerhalb des Blocks liegt.
|
||||
private bool SpanEnthaeltTimoLaframZeit(MitarbeiterstundenkontoRO.DayDetail dayDetail, DateTime spanStart, DateTime spanEnde)
|
||||
{
|
||||
if (dayDetail.ServiceRecords == null)
|
||||
return false;
|
||||
|
||||
foreach (var sr in dayDetail.ServiceRecords)
|
||||
{
|
||||
if (!IstTimoLaframRecord(sr))
|
||||
continue;
|
||||
|
||||
if (sr.Start >= spanStart && sr.Start < spanEnde)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Claude: Erkennt den Klienten "Timo Lafram" über den Namen (Vorname + Nachname, Groß/Klein und
|
||||
// Leerzeichen unkritisch). Ergebnis wird je CustomerOid gecacht.
|
||||
private bool IstTimoLaframRecord(StundenkontoServiceRecord sr)
|
||||
{
|
||||
if (sr == null || !sr.CustomerOid.HasValue)
|
||||
return false;
|
||||
|
||||
long oid = sr.CustomerOid.Value;
|
||||
bool istTimo;
|
||||
if (_IstTimoLaframCache.TryGetValue(oid, out istTimo))
|
||||
return istTimo;
|
||||
|
||||
istTimo = false;
|
||||
var customer = sr.Customer;
|
||||
if (customer != null && customer.Person != null)
|
||||
{
|
||||
var vorname = (customer.Person.FirstName ?? "").Trim();
|
||||
var nachname = (customer.Person.LastName ?? "").Trim();
|
||||
|
||||
istTimo = vorname.Equals("Timo", StringComparison.OrdinalIgnoreCase)
|
||||
&& nachname.Equals("Lafram", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
_IstTimoLaframCache[oid] = istTimo;
|
||||
return istTimo;
|
||||
}
|
||||
|
||||
public override decimal? GetSollStundenForAbsenceTime(MitarbeiterstundenkontoRO.EmployeeDetail ed, AbsenceTime at, DateTime datum)
|
||||
{
|
||||
var key = String.Format("{0}_{1:yyyyMMdd}", ed.Employee.Oid, datum);
|
||||
|
||||
Reference in New Issue
Block a user