228 lines
11 KiB
C#
228 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Service.DCEntityMapper;
|
|
using BeWo.Service.Plugins;
|
|
using BS.Shared;
|
|
using BS.Shared.Core;
|
|
using BS.Shared.DataContracts;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Services;
|
|
|
|
namespace BeWo.Report.ReportObjects
|
|
{
|
|
public class LwvKASpitzabrechnungRO : AbstractBeWoReportObject<LwvKASpitzabrechnungRO>
|
|
{
|
|
public SupportConceptCostBearerRelDC Costbearer2SupportConceptDC { get; set; }
|
|
public CustomerDC CustomerDC { get; set; }
|
|
public DateTime BewilligtStart { get; set; }
|
|
public DateTime BewilligtEnde { get; set; }
|
|
public List<LwvKASpitzabrechnungsWochenZeile> WochenZeilen { get; set; }
|
|
public List<Preiszeitraum> Preiszeitraeume { get; set; }
|
|
public decimal SummeBewilligteStunden { get; set; }
|
|
public decimal SummeErbrachteStunden { get; set; }
|
|
public decimal SummeStundenDifferenz { get; set; }
|
|
public decimal SummeBetragPauschal { get; set; }
|
|
public decimal SummeBetragErbracht { get; set; }
|
|
|
|
|
|
public static LwvKASpitzabrechnungRO Create(long c2sOid, DateTime end, long? scapOid, long? catOid)
|
|
{
|
|
var ro = new LwvKASpitzabrechnungRO();
|
|
var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(c2sOid);
|
|
ro.Costbearer2SupportConceptDC = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(c2s);
|
|
ro.CustomerDC = MapperFactory.CustomerDC_Customer.MapToNewDC(c2s.SupportConcept.Customer);
|
|
ro.BewilligtStart = c2s.StartDate.Value;
|
|
ro.BewilligtEnde = c2s.EndDate.Value;
|
|
if (end < ro.BewilligtEnde)
|
|
{
|
|
ro.BewilligtEnde = end;
|
|
}
|
|
SupportConceptApprovalPeriodDC scap;
|
|
|
|
var calc = PluginLoader.FindClass<Calculations>();
|
|
|
|
// Für Aufruf aus Spitzabrechnung mit scapOid, ansonsten als Bericht mit Auswahl der Leistungskategorie für alle user bzw. ggf. im CustomReportCreator anpassen
|
|
if (!scapOid.HasValue)
|
|
{
|
|
if (catOid.HasValue)
|
|
{
|
|
scap = ro.Costbearer2SupportConceptDC.ApprovalPeriodList.FirstOrDefault(i => ro.BewilligtStart.InBetween(i.Span, true) && i.ServiceCategory.ServiceCategoryOid == catOid.Value);
|
|
if (scap == null || catOid.HasValue && scap.ServiceCategory.ServiceCategoryOid != catOid.Value)
|
|
{
|
|
return ro;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scap = ro.Costbearer2SupportConceptDC.ApprovalPeriodList.FirstOrDefault(i => ro.BewilligtStart.InBetween(i.Span, true));
|
|
//&& i.ServiceCategory != null && (i.ServiceCategory.Name.StartsWith("Kompensatorisch") || (i.ServiceCategory.Name.Contains("KA") && !i.ServiceCategory.Name.Contains("Fahrzeit"))));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scap = ro.Costbearer2SupportConceptDC.ApprovalPeriodList.FirstOrDefault(i => i.SupportConceptApprovalPeriodOid == scapOid.Value);
|
|
}
|
|
|
|
var bewilligtProWoche = scap.ApprovedBEPerInterval ?? 0;
|
|
ro.WochenZeilen = new List<LwvKASpitzabrechnungsWochenZeile>();
|
|
ro.Preiszeitraeume = new List<Preiszeitraum>();
|
|
var zeilenDict = new Dictionary<String, LwvKASpitzabrechnungsWochenZeile>();
|
|
int year = ro.BewilligtStart.Year;
|
|
int idx = 0;
|
|
|
|
|
|
//Erstelle über gesamten Bewilligungszeitraum eine leere Zeile pro Kalenderwoche und Jahr und fülle mit Bewilligungsdaten
|
|
DateTime dt = ro.BewilligtStart;
|
|
while (dt <= ro.BewilligtEnde)
|
|
{
|
|
String kwKey = String.Format("{0}_{1}", dt.Year, GetKW(dt));
|
|
if (!zeilenDict.ContainsKey(kwKey))
|
|
{
|
|
//Neue KW
|
|
var wz = new LwvKASpitzabrechnungsWochenZeile();
|
|
var days = 1;
|
|
wz.Kalenderwoche = GetKW(dt);
|
|
wz.kwStartDate = dt;
|
|
wz.kwEndDate = dt;
|
|
while (wz.kwEndDate.DayOfWeek != DayOfWeek.Sunday)
|
|
{
|
|
wz.kwEndDate = wz.kwEndDate.AddDays(1);
|
|
days += 1;
|
|
}
|
|
wz.bewilligteStunden = Math.Round(bewilligtProWoche/60, 2, MidpointRounding.AwayFromZero);
|
|
if (days != 7)
|
|
{
|
|
wz.bewilligteStunden = Math.Round(wz.bewilligteStunden / 7 * days, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
var data = calc.GetFixedBillingData(scap, wz.kwStartDate, wz.kwEndDate);
|
|
if (data != null && data.Count != 0)
|
|
{
|
|
wz.Stundensatz = data[0].AmountTotal;
|
|
}
|
|
// Der LWV hat für die Kompensatorische Assistenz sich vom Stundensatz auf einen
|
|
wz.BetragPauschal = Math.Round(bewilligtProWoche * (decimal)Math.Round((double)wz.Stundensatz / 60, 4, MidpointRounding.AwayFromZero), 2, MidpointRounding.AwayFromZero);
|
|
ro.SummeBewilligteStunden += wz.bewilligteStunden;
|
|
ro.SummeBetragPauschal += wz.BetragPauschal ?? 0;
|
|
|
|
ro.WochenZeilen.Add(wz);
|
|
zeilenDict.Add(kwKey, wz);
|
|
|
|
// setze Jahresdaten
|
|
if (idx == 0 || year != dt.Year)
|
|
{
|
|
idx++;
|
|
year = dt.Year;
|
|
var pz = new Preiszeitraum();
|
|
pz.Index = idx;
|
|
pz.Stundensatz = wz.BetragPauschal;
|
|
pz.SummeBewilligteStunden = wz.bewilligteStunden;
|
|
pz.SummeErbrachteStunden = 0;
|
|
pz.SummeStundenDifferenz = 0;
|
|
pz.SummeBetragPauschal = 0;
|
|
pz.SummeBetragErbracht = 0;
|
|
pz.SummeBetragDifferenz = 0;
|
|
ro.Preiszeitraeume.Add(pz);
|
|
}
|
|
else
|
|
{
|
|
var aktPz = ro.Preiszeitraeume.FirstOrDefault(i => i.Index == idx);
|
|
aktPz.SummeBewilligteStunden += wz.bewilligteStunden;
|
|
}
|
|
wz.Preiszeitraum = idx;
|
|
}
|
|
|
|
dt = dt.AddDays(1);
|
|
}
|
|
|
|
// ergänze jede Kalenderwoche mit erbrachten Leistungen und den darausfolgenden Daten
|
|
var srList = c2s.ServiceRecords;
|
|
foreach (var item in srList)
|
|
{
|
|
if (item.Start <= end)
|
|
{
|
|
String kwKey = String.Format("{0}_{1}", item.Start.Value.Year, GetKW(item.Start.Value));
|
|
if (zeilenDict.ContainsKey(kwKey) && item.ServiceDescription.ServiceCategory.Oid == scap.ServiceCategory.ServiceCategoryOid)
|
|
{
|
|
var wz = zeilenDict[kwKey];
|
|
wz.erbrachteStunden += item.RoundedDuration / 60;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var wz in ro.WochenZeilen)
|
|
{
|
|
wz.erbrachteStunden = Math.Round(wz.erbrachteStunden, 2, MidpointRounding.AwayFromZero);
|
|
wz.StundenDifferenz = wz.erbrachteStunden - wz.bewilligteStunden;
|
|
if (wz.StundenDifferenz < 0)
|
|
{
|
|
wz.nichtErbrachteStunden = wz.bewilligteStunden - wz.erbrachteStunden;
|
|
}
|
|
if (wz.StundenDifferenz > 0)
|
|
{
|
|
wz.nachgeholteStunden = wz.erbrachteStunden - wz.bewilligteStunden;
|
|
}
|
|
wz.BetragErbracht = Math.Round(wz.erbrachteStunden * wz.Stundensatz.Value, 2, MidpointRounding.AwayFromZero);
|
|
wz.BetragPauschal = Math.Round(bewilligtProWoche * (decimal)Math.Round((double)wz.Stundensatz / 60, 4, MidpointRounding.AwayFromZero), 2, MidpointRounding.AwayFromZero);
|
|
|
|
ro.SummeStundenDifferenz += wz.StundenDifferenz ?? 0;
|
|
ro.SummeErbrachteStunden += wz.erbrachteStunden;
|
|
ro.SummeBetragErbracht += wz.BetragErbracht ?? 0;
|
|
|
|
// Fülle die Jahresdaten
|
|
var aktPz = ro.Preiszeitraeume.FirstOrDefault(i => i.Index == wz.Preiszeitraum);
|
|
aktPz.SummeErbrachteStunden += wz.erbrachteStunden;
|
|
aktPz.SummeStundenDifferenz += wz.StundenDifferenz;
|
|
aktPz.SummeBetragPauschal += wz.BetragPauschal;
|
|
aktPz.SummeBetragErbracht += wz.BetragErbracht;
|
|
}
|
|
|
|
foreach (var pz in ro.Preiszeitraeume)
|
|
{
|
|
//pz.SummeBetragDifferenz = pz.SummeBetragErbracht - pz.SummeBetragPauschal;
|
|
pz.SummeBetragDifferenz = Math.Round(pz.SummeStundenDifferenz.Value * pz.Stundensatz.Value, 2, MidpointRounding.AwayFromZero);
|
|
}
|
|
return ro;
|
|
}
|
|
|
|
private static int GetKW(DateTime actualDate)
|
|
{
|
|
Calendar objCal = CultureInfo.CurrentCulture.Calendar;
|
|
int weekofyear = objCal.GetWeekOfYear(actualDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
|
|
|
|
return weekofyear;
|
|
}
|
|
}
|
|
|
|
public class LwvKASpitzabrechnungsWochenZeile
|
|
{
|
|
public int Preiszeitraum { get; set; }
|
|
public List<ServiceRecordDC> ServiceRecords { get; set; }
|
|
public int Kalenderwoche { get; set; }
|
|
public DateTime kwStartDate { get; set; }
|
|
public DateTime kwEndDate { get; set; }
|
|
public decimal bewilligteStunden { get; set; }
|
|
public decimal erbrachteStunden { get; set; }
|
|
public decimal? nichtErbrachteStunden { get; set; }
|
|
public decimal? nachgeholteStunden { get; set; }
|
|
public decimal? StundenDifferenz { get; set; }
|
|
public decimal? Stundensatz { get; set; }
|
|
public decimal? BetragPauschal { get; set; }
|
|
public decimal? BetragErbracht { get; set; }
|
|
}
|
|
|
|
public class Preiszeitraum
|
|
{
|
|
public int Index { get; set; }
|
|
public decimal? Stundensatz { get; set; }
|
|
public decimal? SummeBewilligteStunden { get; set; }
|
|
public decimal? SummeErbrachteStunden { get; set; }
|
|
public decimal? SummeStundenDifferenz { get; set; }
|
|
public decimal? SummeBetragPauschal { get; set; }
|
|
public decimal? SummeBetragErbracht { get; set; }
|
|
public decimal? SummeBetragDifferenz { get; set; }
|
|
}
|
|
} |