Files
BeWoPlaner/Service/Plugins/FlexibleReportService.cs
2025-11-28 14:54:24 +01:00

421 lines
18 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared.Services;
using Utils = BS.Shared.Core.Utils;
namespace BeWo.Service.Plugins
{
public class FlexibleReportService : AbstractIDSpecificDefaultClass<FlexibleReportService>
{
private Dictionary<long, IList<CostRatePeriodDC>> _CategoryOid2Stundensatz;
private Dictionary<long, IList<CostRatePeriodDC>> _LeistungOid2Stundensatz;
private Dictionary<long, IList<CostRatePeriodDC>> _CostbearerOid2Stundensatz;
private Dictionary<long, IList<CostRatePeriodDC>> _CostbearerOid2RateFactor;
public virtual FlexibleReportResultDC GetAllFlexibleReportEntrys(FlexibleReportFilterDC filter)
{
var result = new FlexibleReportResultDC
{
StartDatum = filter.StartDatum,
EndDatum = filter.EndDatum
};
var calc = PluginLoader.FindClass<Calculations>();
var filterZeitraum = new DateTimeSpan() { StartDateTime = filter.StartDatum.Date, EndDateTime = filter.EndDatum.Date.AddDays(1).AddTicks(-1) };
// Erstellt die FlexibleReportDummies
if (filter.AlleHilfeplaneAnzeigen.HasValue && filter.AlleHilfeplaneAnzeigen.Value)
{
var alleHelp = DAOFactory.GenericDAO.GetAllActiveAndArchived<SupportConcept>().ToArray();
if (alleHelp.Length > 0)
{
var dummies = GetFlexibleReportResult_Dummies(alleHelp, filterZeitraum, calc,
filter.SollAnzeigen.HasValue && filter.SollAnzeigen.Value);
result.Dummies = dummies.ToList();
}
}
// Erstellt die FlexibleReportEntries
if (filter.AlleServiceBerichteAnzeigen.HasValue && filter.AlleServiceBerichteAnzeigen.Value)
{
var alleRec = DAOFactory.SearchDAO.FindServiceRecordsInSpan(filterZeitraum, null).ToArray();
if (alleRec.Length > 0)
{
var entries = GetFlexibleReportResult_Entries(alleRec,
filter.IstAnzeigen.HasValue && filter.IstAnzeigen.Value,
filter.BetragAnzeigen.HasValue && filter.BetragAnzeigen.Value,
filter.GefahreneKilometerAnzeigen.HasValue && filter.GefahreneKilometerAnzeigen.Value);
result.Entries = entries.ToList();
}
}
// Erstellt CustomerDic
if (filter.AlleKlientenAnzeigen.HasValue && filter.AlleKlientenAnzeigen.Value)
{
var alleCos = DAOFactory.GenericDAO.GetAllActive<Customer>();
if (alleCos.Count > 0)
{
var customers = GetFlexibleReportResult_Customers(alleCos);
result.Customers = customers;
}
}
// Erstellt EmployeeDic
if (filter.AlleMitarbeiterAnzeigen.HasValue && filter.AlleMitarbeiterAnzeigen.Value)
{
var alleEmps = DAOFactory.GenericDAO.GetAllActive<Employee>();
if (alleEmps.Count > 0)
{
var employees = GetFlexibleReportResult_Employees(alleEmps);
result.Employees = employees;
}
}
return result;
}
protected virtual decimal? GetStundensatz(ServiceRecord sr)
{
if (_CategoryOid2Stundensatz == null)
BuildStundensatzDictionaries();
if (sr.CostBearer2SupportConcept != null)
{
if (_LeistungOid2Stundensatz.ContainsKey(sr.ServiceDescription.Oid.Value))
{
var crList = _LeistungOid2Stundensatz[sr.ServiceDescription.Oid.Value];
var cr = crList.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, sr.Start.Value);
if (cr != null && cr.CostRateValue.HasValue)
{
return cr.CostRateValue.Value;
}
}
if (_CategoryOid2Stundensatz.ContainsKey(sr.ServiceDescription.ServiceCategory.Oid.Value))
{
var crList = _CategoryOid2Stundensatz[sr.ServiceDescription.ServiceCategory.Oid.Value];
var cr = crList.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, sr.Start.Value);
if (cr != null && cr.CostRateValue.HasValue)
{
return cr.CostRateValue.Value;
}
}
if (_CostbearerOid2Stundensatz.ContainsKey(sr.CostBearer2SupportConcept.CostBearer.Oid.Value))
{
var crList = _CostbearerOid2Stundensatz[sr.CostBearer2SupportConcept.CostBearer.Oid.Value];
var cr = crList.GetCostRatePeriodForDate(CostRatePeriodType.HourlyRate, sr.Start.Value);
if (cr?.CostRateValue != null)
{
var betrag = cr.CostRateValue.Value;
if (_CostbearerOid2RateFactor.ContainsKey(sr.CostBearer2SupportConcept.CostBearer.Oid.Value))
{
crList = _CostbearerOid2RateFactor[sr.CostBearer2SupportConcept.CostBearer.Oid.Value];
cr = crList.GetCostRatePeriodForDate(CostRatePeriodType.RateFactor, sr.Start.Value);
if (cr?.CostRateValue != null)
{
betrag *= 1 + cr.CostRateValue.Value / 100;
}
}
return betrag;
}
}
}
return null;
}
protected virtual void BuildStundensatzDictionaries()
{
_CategoryOid2Stundensatz = new Dictionary<long, IList<CostRatePeriodDC>>();
_LeistungOid2Stundensatz = new Dictionary<long, IList<CostRatePeriodDC>>();
_CostbearerOid2Stundensatz = new Dictionary<long, IList<CostRatePeriodDC>>();
_CostbearerOid2RateFactor = new Dictionary<long, IList<CostRatePeriodDC>>();
var categories = DAOFactory.GenericDAO.GetAllActive<ServiceCategory>();
foreach (var cat in categories)
{
if (cat.AccountingInterval.HasValue && cat.AccountingInterval.Value == AccountingIntervalType.Hourly)
{
var hrCats = cat.CostRatePeriods.ToList();
if (hrCats.Count > 0)
{
_CategoryOid2Stundensatz.Add(cat.Oid.Value, MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(hrCats));
}
}
}
var descriptions = DAOFactory.GenericDAO.GetAllActive<ServiceDescription>();
foreach (var desc in descriptions)
{
if (desc.AccountingInterval.HasValue && desc.AccountingInterval.Value == AccountingIntervalType.Hourly)
{
var hrCats = desc.CostRatePeriods.ToList();
if (hrCats.Count > 0)
{
_LeistungOid2Stundensatz.Add(desc.Oid.Value, MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(hrCats));
}
}
}
var costBearers = DAOFactory.GenericDAO.GetAllActive<CostBearer>();
foreach (var cb in costBearers)
{
var hrCats = cb.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.HourlyRate).ToList();
if (hrCats.Count > 0)
{
_CostbearerOid2Stundensatz.Add(cb.Oid.Value, MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(hrCats));
}
var rfCats = cb.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.RateFactor).ToList();
if (rfCats.Count > 0)
{
_CostbearerOid2RateFactor.Add(cb.Oid.Value, MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(rfCats));
}
}
}
protected virtual decimal? GetSollPerDayEmployee(Customer customer, Employee employee, DateTime date, SupportConceptApprovalPeriod scap, Calculations calc)
{
var scapDC = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(scap);
var sollPerDay = calc.GetApprovedHoursPerDay(scapDC, new List<CostRatePeriodDC>()) * 60;
if (employee == null)
return sollPerDay;
var sc2e = scap.SupportConceptApprovalPeriod2Employee.FirstOrDefault(x => x.Employee.Oid == employee.Oid);
if (sc2e != null)
return sc2e.IsAbsolut ? sc2e.Betreuungsschluessel : sollPerDay * sc2e.Betreuungsschluessel/100;
else
return sollPerDay;
}
protected virtual decimal? GetSollPerDay(Customer customer, DateTime date, SupportConceptApprovalPeriod scap, Calculations calc)
{
var scapDC = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(scap);
var sollPerDay = calc.GetApprovedHoursPerDay(scapDC, new List<CostRatePeriodDC>()) * 60;
return sollPerDay;
}
// ToDo: Auslagern / generaliesieren
protected static IEnumerable<Employee> GetHauptbetreuer(Customer c)
{
foreach (Employee2Customer e2c in c.Employee2CustomerList)
{
foreach (ValueListEntry2Object vle2o in e2c.ValueList)
{
var vle = vle2o.Entry;
if (vle.SystemEntryID == SystemEntryID.EmployeeRoleMainAttendant && e2c.CustomerOid == c.Oid)
yield return e2c.Employee;
}
}
}
protected virtual IEnumerable<FlexibleReportEntryDC> GetFlexibleReportResult_Entries(IEnumerable<ServiceRecord> alleRec, bool zeigeIst, bool zeigeBetrag, bool zeigeKilometer)
{
foreach (var serviceRecord in alleRec)
{
if (!serviceRecord.Start.HasValue || !serviceRecord.End.HasValue)
continue;
var entry = new FlexibleReportEntryDC
{
ServiceRecordOid = serviceRecord.Oid,
EndDatum = serviceRecord.End.Value,
Notice = serviceRecord.Notice,
Notice2 = serviceRecord.Notice2,
Notice3 = serviceRecord.Notice3,
Notice4 = serviceRecord.Notice4,
Notice5 = serviceRecord.Notice5,
SollArbeitszeitMinuten = null,
SollBetreuungszeitMinuten = null,
StartDatum = serviceRecord.Start.Value,
Leistung = serviceRecord.ServiceDescription.Name,
Leistungskategorie = serviceRecord.ServiceDescription.ServiceCategory.Name
};
if (zeigeIst || zeigeBetrag)
{
entry.IstArbeitszeitMinuten = serviceRecord.RoundedDuration;
entry.IstBetreuungszeitMinuten = serviceRecord.RoundedDuration;
if (serviceRecord.GroupEmployeeCount.HasValue && serviceRecord.GroupEmployeeCount.Value > 1)
{
entry.IstBetreuungszeitMinuten /= serviceRecord.GroupEmployeeCount.Value;
}
}
if (zeigeBetrag)
{
entry.Stundensatz = GetStundensatz(serviceRecord);
entry.Betrag = (entry.IstBetreuungszeitMinuten / 60) * entry.Stundensatz;
}
if (zeigeKilometer)
{
entry.Kilometer = (int?)serviceRecord.DistanceInMeter;
entry.KilometerDecimal = serviceRecord.DistanceInMeter;
}
if (serviceRecord.Customer != null)
{
entry.CustomerOid = serviceRecord.Customer.Oid;
entry.CustomerString = serviceRecord.Customer.Person.LastNameFirstName;
entry.Team = serviceRecord.Customer.TeamSimpleString;
}
if (serviceRecord.Employee != null)
{
entry.EmployeeOid = serviceRecord.Employee.Oid;
entry.EmployeeString = serviceRecord.Employee.Person.LastNameFirstName;
}
if (serviceRecord.SupportConcept != null)
{
entry.SupportConceptOid = serviceRecord.SupportConcept.Oid;
entry.SupportConceptString = serviceRecord.SupportConcept.TimeSpanString;
}
if (serviceRecord.CostBearer2SupportConcept != null)
{
entry.Organisation = serviceRecord.CostBearer2SupportConcept.CostBearer.Organisation.Name;
}
yield return entry;
}
}
protected virtual IEnumerable<FlexibleReportDummyDC> GetFlexibleReportResult_Dummies(IList<SupportConcept> alleHelp, DateTimeSpan filterZeitraum, Calculations calc, bool zeigeSoll)
{
foreach (var hilfePlan in alleHelp.Where(x => filterZeitraum.StartDate <= x.EndDate && filterZeitraum.EndDate >= x.StartDate))
{
foreach (var c2s in hilfePlan.CostBearer2SupportConceptList.Where(x => filterZeitraum.StartDate <= x.EndDate && filterZeitraum.EndDate >= x.StartDate))
{
foreach (var approvalPeriod in c2s.ApprovalPeriodList.Where(x => filterZeitraum.StartDate <= x.EndDate && filterZeitraum.EndDate >= x.StartDate))
{
var start = filterZeitraum.StartDate > approvalPeriod.StartDate ? filterZeitraum.StartDate : approvalPeriod.StartDate.Value;
var ende = filterZeitraum.EndDate < approvalPeriod.EndDate ? filterZeitraum.EndDate : approvalPeriod.EndDate.Value;
var zeitraum = new DateTimeSpan(start, ende);
// Wenn kein Mitarbeiter dem Bewilligungszeitraum zugewiesen ist
if (approvalPeriod.SupportConceptApprovalPeriod2Employee.Count == 0)
{
var hauptbetreuer = GetHauptbetreuer(hilfePlan.Customer).ToList();
var soll = zeigeSoll ? GetSollPerDay(hilfePlan.Customer, start, approvalPeriod, calc) : null;
// Wenn der Klient keine Hauptbetreuer hat
if (hauptbetreuer.Count == 0)
{
yield return GetFlexibleReportDummy(hilfePlan.Customer, null, zeitraum, hilfePlan, approvalPeriod, soll, null);
}
// Wenn der Klient ein oder mehr Hauptbetreuer hat
else
{
var sollAnteil = soll / hauptbetreuer.Count;
foreach (var betreuer in hauptbetreuer)
{
yield return GetFlexibleReportDummy(hilfePlan.Customer, betreuer, zeitraum, hilfePlan, approvalPeriod, sollAnteil, null);
}
}
}
// Wenn ein oder mehr Mitarbeiter dem Bewilligungszeitraum zugewiesen ist/sind
else
{
foreach (var s2e in approvalPeriod.SupportConceptApprovalPeriod2Employee)
{
var soll = zeigeSoll ? GetSollPerDayEmployee(hilfePlan.Customer, s2e.Employee, approvalPeriod.StartDate.Value, approvalPeriod, calc) : null;
yield return GetFlexibleReportDummy(hilfePlan.Customer, s2e.Employee, zeitraum, hilfePlan, approvalPeriod, soll, null);
}
}
}
}
}
}
protected virtual FlexibleReportDummyDC GetFlexibleReportDummy(Customer customer, Employee employee, DateTimeSpan timeSpan, SupportConcept supportConcept, SupportConceptApprovalPeriod approvalPeriod, decimal? sollBetreuungszeit, decimal? sollArbeitszeit)
{
var dummy = new FlexibleReportDummyDC
{
CustomerOid = customer.Oid,
CustomerString = customer.Person.LastNameFirstName,
SupportConceptOid = supportConcept.Oid,
SupportConceptString = supportConcept.TimeSpanString,
StartDate = timeSpan.StartDate.Date,
EndDate = timeSpan.EndDate.Date,
SollBetreuungszeit = sollBetreuungszeit,
SollArbeitszeit = sollArbeitszeit
};
if (employee != null)
{
dummy.EmployeeOid = employee.Oid;
dummy.EmployeeString = employee.Person.LastNameFirstName;
}
if (approvalPeriod != null)
{
dummy.Leistungskategorie = approvalPeriod.ServiceCategory?.Name;
dummy.Organisation = approvalPeriod.CostBearer2SupportConcept.CostBearer.Organisation.Name;
}
return dummy;
}
protected virtual Dictionary<long, string> GetFlexibleReportResult_Customers(IList<Customer> customers)
{
var customerDic = new Dictionary<long, string>();
foreach (var customer in customers)
{
customerDic.Add(customer.Oid.Value, string.Format("{0}, {1}", customer.Person.LastName, customer.Person.FirstName));
}
return customerDic;
}
protected virtual Dictionary<long, string> GetFlexibleReportResult_Employees(IList<Employee> employees)
{
var employeeDic = new Dictionary<long, string>();
foreach (var employee in employees)
{
employeeDic.Add(employee.Oid.Value, string.Format("{0}, {1}", employee.Person.LastName, employee.Person.FirstName));
}
return employeeDic;
}
}
}