From 3dbdaad1b5a58c0e5dacc77db504eb165f437e26 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Mon, 1 Jun 2026 10:44:14 +0200 Subject: [PATCH 1/3] MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs - bei Soziotherapie Faktor auf erbrachte Zeit SupportOID=163414 --- .../MalteserJohanniterJohanneshaus.csproj | 1 + .../CustomServiceRecordStatisticFactory.cs | 104 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs diff --git a/ReportImp/MalteserJohanniterJohanneshaus/MalteserJohanniterJohanneshaus.csproj b/ReportImp/MalteserJohanniterJohanneshaus/MalteserJohanniterJohanneshaus.csproj index 8b93dcafe..9ba4ed4bd 100644 --- a/ReportImp/MalteserJohanniterJohanneshaus/MalteserJohanniterJohanneshaus.csproj +++ b/ReportImp/MalteserJohanniterJohanneshaus/MalteserJohanniterJohanneshaus.csproj @@ -153,6 +153,7 @@ + Component diff --git a/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs b/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs new file mode 100644 index 000000000..cbb48b370 --- /dev/null +++ b/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs @@ -0,0 +1,104 @@ +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BeWo.Service.Plugins; +using BS.Shared.DataContracts; +using DevExpress.Office.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MalteserJohanniterJohanneshaus.Service +{ + public class CustomServiceRecordStatisticFactory : ServiceRecordStatisticFactory + { + public override SupportConceptStatisticsDC CreateSupportConceptStatisticsImpl(long costBearer2SupportConceptOid, DateTime statisticsDate, long? ignoreServiceRecordOid) + { + var stats = base.CreateSupportConceptStatisticsImpl(costBearer2SupportConceptOid, statisticsDate, ignoreServiceRecordOid); + + try + { + if (stats.PeriodStatistics.Any(p => p.SupportConceptApprovalPeriod.ServiceCategory != null && String.IsNullOrEmpty(p.SupportConceptApprovalPeriod.ServiceCategory.Name) + && p.SupportConceptApprovalPeriod.ServiceCategory.Name == "Soziotherapie")) + { + + decimal factor = 1.2m; + + stats.IstTotalUntilThisMonth *= factor; + stats.MinutesFreePerMonthAverage *= factor; + stats.MinutesFreePerWeekAverage *= factor; + stats.MinutesOutOfApprovedPeriod *= factor; + stats.MinutesProvidedPerMonthAverage *= factor; + stats.MinutesProvidedPerWeekAverage *= factor; + stats.MinutesProvidedThisMonth *= factor; + stats.MinutesProvidedThisWeek *= factor; + stats.MinutesProvidedTotal *= factor; + stats.MinutesProvidedTotalRounded *= factor; + + foreach (var s in stats.PeriodStatistics) + { + s.AmountConsumedThisInterval *= factor; + s.AmountConsumedTotal *= factor; + s.IstTotalUntilThisMonth *= factor; + s.MinutesFreePerWeek *= factor; + s.MinutesOutOfApprovedPeriod *= factor; + s.MinutesProvidedThisMonth *= factor; + s.MinutesProvidedThisWeek *= factor; + s.MinutesProvidedTotal *= factor; + s.MinutesProvidedTotalRounded *= factor; + s.SollTotalUntilThisMonth *= factor; + + SetMinutesFreePerWeek(stats, s); + } + } + + return stats; + } + catch + { + return stats; + } + } + + private void SetMinutesFreePerWeek(SupportConceptStatisticsDC stat, SupportConceptPeriodStatisticsDC ps) + { + try + { + DateTime dtPeriod = stat.DateOfCreation.Date; + if (ps.SupportConceptApprovalPeriod.StartDate.HasValue && ps.SupportConceptApprovalPeriod.EndDate.HasValue) + { + if (ps.SupportConceptApprovalPeriod.StartDate.HasValue && ps.SupportConceptApprovalPeriod.StartDate > dtPeriod) + { + dtPeriod = ps.SupportConceptApprovalPeriod.StartDate.Value; + } + TimeSpan tsPeriod = ps.SupportConceptApprovalPeriod.EndDate.Value.Subtract(dtPeriod); + int daysPeriod = tsPeriod.Days + 1; + if (daysPeriod < 0) + { + daysPeriod = 0; + } + if (daysPeriod != 0) + { + ps.MinutesFreePerWeek = (ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded) / (daysPeriod / 7m); + ps.MinutesFreePerWeekStatisticDate = (ps.MinutesApprovedTotal - ps.IstTotalUntilThisMonth - ps.MinutesProvidedThisMonth) / (daysPeriod / 7m); + ps.MinutesFreePerMonth = (ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded) / (daysPeriod / 7m) * (365m / 84m); + ps.MinutesFreePerMonthStatisticDate = (ps.MinutesApprovedTotal - ps.IstTotalUntilThisMonth - ps.MinutesProvidedThisMonth) / (daysPeriod / 7m) * (365m / 84m); + } + else // Bewilligung ist abgelaufen + { + ps.MinutesFreePerWeek = ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded; + ps.MinutesFreePerWeekStatisticDate = ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded; + ps.MinutesFreePerMonth = ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded; + ps.MinutesFreePerMonthStatisticDate = ps.MinutesApprovedTotal - ps.MinutesProvidedTotalRounded; + } + } + } + catch (Exception) + { + //Mach nichts. Das ist für den alten Mok bei dem die Felder MinutesFreePerWeekStatisticDate noch nicht in der alten Shared.dll existieren + } + } + } +} From 60f92b8c4bf20a87a103ede398fdb0fca0958605 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Mon, 1 Jun 2026 15:11:08 +0200 Subject: [PATCH 2/3] MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs - Nachtrag Logik SupportOID=164077 --- .../Service/CustomServiceRecordStatisticFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs b/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs index cbb48b370..c237509cd 100644 --- a/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs +++ b/ReportImp/MalteserJohanniterJohanneshaus/Service/CustomServiceRecordStatisticFactory.cs @@ -20,7 +20,7 @@ namespace MalteserJohanniterJohanneshaus.Service try { - if (stats.PeriodStatistics.Any(p => p.SupportConceptApprovalPeriod.ServiceCategory != null && String.IsNullOrEmpty(p.SupportConceptApprovalPeriod.ServiceCategory.Name) + if (stats.PeriodStatistics.Any(p => p.SupportConceptApprovalPeriod.ServiceCategory != null && !String.IsNullOrEmpty(p.SupportConceptApprovalPeriod.ServiceCategory.Name) && p.SupportConceptApprovalPeriod.ServiceCategory.Name == "Soziotherapie")) { From 2d7114bcf0573841c50e85d4b1920822c1e61d77 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Mon, 1 Jun 2026 15:28:58 +0200 Subject: [PATCH 3/3] LebenshilfeStade/Service/CustomServiceRecordValidator - Hinweise zu Fehlkontakten und Abwesenheiten SupportOID=163661 --- .../Service/CustomServiceRecordValidator.cs | 90 ++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/ReportImp/LebenshilfeStade/Service/CustomServiceRecordValidator.cs b/ReportImp/LebenshilfeStade/Service/CustomServiceRecordValidator.cs index 983eda4a8..bbc582e71 100644 --- a/ReportImp/LebenshilfeStade/Service/CustomServiceRecordValidator.cs +++ b/ReportImp/LebenshilfeStade/Service/CustomServiceRecordValidator.cs @@ -1,6 +1,11 @@ -using BeWo.Service.Plugins; +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BeWo.Service.Plugins; +using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.Extensions; +using BS.Shared.Services; using System; using System.Collections.Generic; using System.Linq; @@ -31,6 +36,89 @@ namespace LebenshilfeStade.Service validation.Add(res); } + // Warnung bei Fehlkontakt: max. 5 in 90 Tagen erlaubt + if (newServiceRecord.ServiceDescription?.Name == "Fehlkontakt") + { + long? fehlkontaktCb2ScOid = null; + if (newServiceRecord.SupportConcept != null && newServiceRecord.CostBearer != null && newServiceRecord.CostBearer2SupportConceptOid.HasValue) + { + fehlkontaktCb2ScOid = newServiceRecord.CostBearer2SupportConceptOid.Value; + } + if (fehlkontaktCb2ScOid.HasValue) + { + var now = newServiceRecord.Start ?? DateTime.Now; + var since90Days = now.AddDays(-90); + var recentRecords = DAOFactory.SearchDAO.FindServiceRecordsDetailsForLastDaysWithStartEndDate(fehlkontaktCb2ScOid.Value, since90Days, now); + int fehlkontaktCount = recentRecords.Count(r => r.ServiceDescription?.Name == "Fehlkontakt" && r.Oid != newServiceRecord.ServiceRecordOid); + if (fehlkontaktCount >= 3) + { + validation.Add(new ServiceRecordValidationResultDC + { + ResultType = ServiceRecordValidationResult.Custom, + Message = "Bitte beachten Sie, dass maximal 5 Fehlkontakte innerhalb von 90 Tagen seitens des Kostenträgers erlaubt sind.\nMöchten Sie trotzdem speichern?", + Allow = true + }); + } + } + } + + if (newServiceRecord.ServiceDescription.Category.IsBillable) + { + var startDate = newServiceRecord.Start.Value; + var endDate = newServiceRecord.End.Value; + var klientenoid = newServiceRecord.SupportConcept?.Customer?.CustomerOid; + if (klientenoid is object) + { + long? cb2ScOid = null; + if (newServiceRecord.SupportConcept != null && newServiceRecord.CostBearer != null && newServiceRecord.CostBearer2SupportConceptOid.HasValue) + { + cb2ScOid = newServiceRecord.CostBearer2SupportConceptOid.Value; + } + if (cb2ScOid.HasValue) + { + SupportConceptCostBearerRelDC reldc = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC( + DAOFactory.GenericDAO.GetByID(cb2ScOid.Value)); + + // Abwesenheitswochen-Hinweis: gestaffelte Abrechnungsregel des Kostenträgers + var absenceTimes = reldc.SupportConcept?.Customer?.AbsenceTimes; + if (absenceTimes != null && absenceTimes.Count > 0) + { + var srDate = (newServiceRecord.Start ?? DateTime.Now).Date; + var activeAbsence = absenceTimes.Where(a => a.Start.HasValue && a.Start.Value.Date <= srDate && (!a.End.HasValue || a.End.Value.Date >= srDate)) + .OrderByDescending(a => a.Start.Value).FirstOrDefault(); + + if (activeAbsence != null) + { + int dayOfAbsence = (int)(srDate - activeAbsence.Start.Value.Date).TotalDays + 1; + int weekNumber = (int)Math.Ceiling(dayOfAbsence / 7.0); + int allowedFls; + if (weekNumber <= 4) + { + allowedFls = 2; + } + else if (weekNumber <= 6) + { + allowedFls = 1; + } + else + { + allowedFls = 0; + } + + var customer = reldc.SupportConcept.Customer; + string customerName = $"{customer.FirstName} {customer.LastName}".Trim(); + validation.Add(new ServiceRecordValidationResultDC + { + ResultType = ServiceRecordValidationResult.Custom, + Message = $"Dies ist die {weekNumber}. Woche der Abwesenheit von {customerName}. Sie dürfen in dieser Woche {allowedFls} Stunden abrechnen.\nMöchten Sie trotzdem speichern?", + Allow = true + }); + } + } + } + } + } + return validation; } }