LWLDigga - Dateien für Abrechnung LWLDigital 1.0

This commit is contained in:
2025-10-09 14:26:01 +02:00
parent 5e36fbb2de
commit 38fc540ee8
9 changed files with 2650 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
using System;
using System.Linq;
using BeWo.Report;
using BeWo.Report.ReportObjects;
namespace BeWo.Report.DefaultReports
{
public partial class BudgetnachweisAnhangDigi : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<BudgetnachweisAnhangDigiRO>
{
public BudgetnachweisAnhangDigi()
{
InitializeComponent();
}
public void SetReportDataSource(BudgetnachweisAnhangDigiRO pRO)
{
bindingSource1.DataSource = pRO;
}
}
}

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="xrLabel1.Text" xml:space="preserve">
<value>Über den Budgetnachweis werden auf Grundlage der Quittierungsbelege im nachstehenden Umfang folgende, im direkten Betreuungskontakt erbrachte Minuten zur Abrechnung beantragt (direkte Fachleistungsminuten = D-FLMin).
Der mittelbarere Leistungsberechtigten-bezogener Zeitaufwand (M-FLMin) kann bis zu 20% der direkten Betreuungszeit aufgeschlagen werden. Entsprechnend der Rundungsvariante 2 wird die Summe aus direkter Betreuungszeit und aufgeschlagener mittelbarer Leistung auf volle 10 Minuten gerundet und in der Spalte M-FLMin einschl. Rundung erfasst.</value>
</data>
</root>

View File

@@ -181,6 +181,12 @@
<Compile Include="DefaultReports\AbwesenheitsPrintReport.Designer.cs">
<DependentUpon>AbwesenheitsPrintReport.cs</DependentUpon>
</Compile>
<Compile Include="DefaultReports\BudgetnachweisAnhangDigi.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="DefaultReports\BudgetnachweisAnhangDigi.Designer.cs">
<DependentUpon>BudgetnachweisAnhangDigi.cs</DependentUpon>
</Compile>
<Compile Include="DefaultReports\Invoices\GkvBegleitzettel.cs">
<SubType>Component</SubType>
</Compile>
@@ -540,6 +546,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="ReportObjects\AbwesenheitsPrintRO.cs" />
<Compile Include="ReportObjects\BudgetnachweisAnhangUngerundetRO.cs" />
<Compile Include="ReportObjects\GkvAbrechnungRO.cs" />
<Compile Include="ReportObjects\LwvKASpitzabrechnungRO.cs" />
<Compile Include="ReportObjects\BudgetnachweisAnhangRO.cs" />
@@ -607,6 +614,9 @@
<DependentUpon>AbwesenheitsPrintReport.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="DefaultReports\BudgetnachweisAnhangDigi.resx">
<DependentUpon>BudgetnachweisAnhangDigi.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="DefaultReports\Invoices\GkvBegleitzettel.resx">
<DependentUpon>GkvBegleitzettel.cs</DependentUpon>
<SubType>Designer</SubType>

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Invoicing;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
namespace BeWo.Report.ReportObjects
{
public class BudgetnachweisAnhangDigiRO : AbstractBeWoReportObject<BudgetnachweisAnhangDigiRO>
{
public LWLDiggaBerechnung LWLDiggaBerechnung { get; set; }
public Settlement2DC SettlementDC { get; set; }
public SupportConceptCostBearerRelDC Costbearer2SupportConceptDC { get; set; }
public CustomerDC CustomerDC { get; set; }
public DateTime BewilligtStart { get; set; }
public DateTime BewilligtEnde { get; set; }
public List<EntgeltzeitraumDigga> Entgeltzeitraeume { get; set; }
public List<BudgetnachweisDiggaMonatsZeile> MonatsZeilen { get; set; }
public void Create(Settlement2DC si)
{
// die gesamte Berechnung ist für Anhang zum Budgetnachweis und für die Berechnung der Rechnung identisch, daher in Extraklasse LWLDiggaBerechnnung gelagert
CostBearer2SupportConcept cb2sc = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(si.CostBearer2SupportConceptOid.Value);
this.BewilligtStart = si.AccountingPeriodStart.Value;
this.BewilligtEnde = si.AccountingPeriodEnd.Value;
LWLDiggaBerechnung = new LWLDiggaBerechnung();
LWLDiggaBerechnung.CreateLWLDiggaBerechnung(si, cb2sc, BewilligtStart, BewilligtEnde);
Customer customer = cb2sc.SupportConcept.Customer;
this.SettlementDC = si;
this.Costbearer2SupportConceptDC = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(cb2sc);
this.CustomerDC = MapperFactory.CustomerDC_Customer.MapToNewDC(customer);
MonatsZeilen = LWLDiggaBerechnung.MonatsZeilen;
}
}
}

View File

@@ -0,0 +1,298 @@
using System;
using System.Collections.Generic;
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.Service.Invoicing
{
public class LWLDiggaBerechnung : AbstractIDSpecificDefaultClass<LWLDiggaBerechnung>
{
public virtual DateTime? Umstellungsdatum()
{
// letzter Tag mit alter Rundung (Variante 1) in Zeitervassung
return null;
}
public virtual bool EndRundung()
{
// ursprünglich ist vom LWL angedacht gewesen, dass nur Rundungsvariante 2 erlaubt ist,
// das heißt, dass die Rundung vom Zeiterfassungseintrag zum Monatsgesamtwert wechselt in dem Moment, wo die digitalen Belege genutzt werden
return true;
}
public DateTime BewilligtStart { get; set; }
public DateTime BewilligtEnde { get; set; }
public List<EntgeltzeitraumDigga> Entgeltzeitraeume { get; set; }
public List<BudgetnachweisDiggaMonatsZeile> MonatsZeilen { get; set; }
public decimal RateFactor { get; set; }
public decimal SummeFLMinuten { get; set; }
public decimal SummeFaktorMinuten { get; set; }
public decimal SummeGesamtMinuten { get; set; }
public decimal SummeFLStunden { get; set; }
public decimal SummeFehlkontakte { get; set; }
public decimal SummeFehlkontakteStunden { get; set; }
public decimal SummeFaktorStunden { get; set; }
public decimal SummeGesamtStunden { get; set; }
public decimal SummeGesamtStundenMitFK { get; set; }
public virtual void CreateLWLDiggaBerechnung(Settlement2DC si, CostBearer2SupportConcept cb2sc, DateTime? BewilligtStart, DateTime? BewilligtEnde)
{
var calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
var serviceRecords = GetBillableServiceRecords(cb2sc);
var relDC = cb2sc.MapToNewDC();
this.BewilligtStart = si.AccountingPeriodStart.Value;
this.BewilligtEnde = si.AccountingPeriodEnd.Value;
MonatsZeilen = new List<BudgetnachweisDiggaMonatsZeile>();
Entgeltzeitraeume = new List<EntgeltzeitraumDigga>();
CreateEntgeltzeitraeume(Entgeltzeitraeume, cb2sc, this.BewilligtStart, this.BewilligtEnde);
var span = new DateTimeSpan();
span.StartDateTime = si.AccountingPeriodStart.Value;
span.EndDateTime = si.AccountingPeriodEnd.Value.AddDays(1).AddTicks(-1);
Dictionary<string, BudgetnachweisDiggaMonatsZeile> monat2Zeile = new Dictionary<string, BudgetnachweisDiggaMonatsZeile>();
DateTime monat = new DateTime(this.BewilligtStart.Year, this.BewilligtStart.Month, this.BewilligtStart.Day);
CalculateMonatsbasisWerte(Entgeltzeitraeume, cb2sc, serviceRecords, span, monat2Zeile, monat);
CalculateMonatsMinutenWerteMitRundung(MonatsZeilen);
foreach (var e in this.Entgeltzeitraeume)
{
e.SummeFaktorStunden = Math.Round(e.SummeFaktorMinuten / 60, 2, MidpointRounding.AwayFromZero);
Math.Round(e.SummeFehlkontakteGerundet / 60, 2, MidpointRounding.AwayFromZero);
e.SummeGesamtStunden = Math.Round(e.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
e.SummeGesamtStundenMitFK = e.SummeFehlkontakteStunden + e.SummeGesamtStunden;
SummeFLMinuten += e.SummeFLMinuten;
SummeFaktorMinuten += e.SummeFaktorMinuten;
SummeGesamtMinuten += e.SummeMinutenGerundet;
SummeFLStunden += e.SummeFLStunden;
SummeFaktorStunden += e.SummeFaktorStunden;
SummeGesamtStunden += e.SummeGesamtStunden;
SummeFehlkontakte += e.SummeFehlkontakte;
SummeFehlkontakteStunden += e.SummeFehlkontakteStunden;
SummeGesamtStundenMitFK += e.SummeGesamtStundenMitFK;
}
}
public virtual IList<ServiceRecord> GetBillableServiceRecords(CostBearer2SupportConcept c2s)
{
return c2s.ServiceRecords.Where(IsServiceRecordBillable).OrderBy(s => s.Start).ToList();
}
public virtual bool IsServiceRecordBillable(ServiceRecord iRecord)
{
return true;
}
private void CalculateMonatsMinutenWerteMitRundung(List<BudgetnachweisDiggaMonatsZeile> MonatsZeilen)
{
DateTime? uDate = Umstellungsdatum();
bool neueRundung = EndRundung();
foreach (var mz in MonatsZeilen)
{
if (!uDate.HasValue || uDate.HasValue && mz.Monat > uDate)
{
mz.SummeMinutenGerundet = Math.Ceiling((mz.SummeFLMinuten + mz.SummeFLMinuten * 0.2m) / 10) * 10;
mz.SummeFLStunden = Math.Round(mz.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
mz.SummeFaktorMinuten = mz.SummeMinutenGerundet - mz.SummeFLMinuten;
mz.SummeFehlkontakteStunden = Math.Round(mz.SummeFehlkontakte / 60, 2, MidpointRounding.AwayFromZero);
mz.SummeGesamtMinutenMitFKGerundet = mz.SummeMinutenGerundet + mz.SummeFehlkontakte;
mz.SummeGesamtStundenMitFKGerundet = Math.Round(mz.SummeGesamtMinutenMitFKGerundet / 60, 2, MidpointRounding.AwayFromZero);
}
else
{
mz.SummeFaktorMinuten = Math.Round(mz.SummeFLMinuten * 0.2m, 2, MidpointRounding.AwayFromZero);
mz.SummeMinutenGerundet = mz.SummeFLMinuten + SummeFaktorMinuten;
mz.SummeFLStunden = Math.Round(mz.SummeMinutenGerundet / 60, 2, MidpointRounding.AwayFromZero);
mz.SummeFehlkontakteStunden = Math.Round(mz.SummeFehlkontakte / 60, 2, MidpointRounding.AwayFromZero);
mz.SummeGesamtMinutenMitFKGerundet = mz.SummeMinutenGerundet + mz.SummeFehlkontakte;
mz.SummeGesamtStundenMitFKGerundet = Math.Round(mz.SummeGesamtMinutenMitFKGerundet / 60, 2, MidpointRounding.AwayFromZero);
}
foreach (var e in Entgeltzeitraeume)
{
if (e.Index == mz.Entgeltzeitraum)
{
e.ServiceRecords.AddRange(mz.ServiceRecords);
e.SummeFLMinuten += mz.SummeFLMinuten;
e.SummeFaktorMinuten += mz.SummeFaktorMinuten;
e.SummeMinutenGerundet += mz.SummeMinutenGerundet;
e.SummeFLStunden += mz.SummeFLStunden;
e.SummeFehlkontakte += mz.SummeFehlkontakte;
e.SummeFehlkontakteStunden += mz.SummeFehlkontakteStunden;
e.SummeGesamtStundenMitFK += mz.SummeGesamtStundenMitFKGerundet;
}
}
}
}
public virtual void CreateEntgeltzeitraeume(List<EntgeltzeitraumDigga> entgeltzeitraeume, CostBearer2SupportConcept cb2sc, DateTime bewilligtStart, DateTime bewilligtEnde)
{
var crList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(cb2sc.CostBearer.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.HourlyRate));
var crRfList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(cb2sc.CostBearer.CostRatePeriods.Where(c => c.CostRateType == CostRatePeriodType.RateFactor));
var rf = crRfList.GetCostRatePeriodForDate(CostRatePeriodType.RateFactor, this.BewilligtEnde);
if (rf != null && rf.CostRateValue.HasValue)
{
this.RateFactor = rf.CostRateValue.Value;
}
foreach (var cr in crList)
{
if (!cr.EndDate.HasValue)
{
cr.EndDate = this.BewilligtEnde.AddDays(1);
}
}
crList = crList.OrderBy(c => c.EndDate).ToList();
DateTime start = DateTime.MinValue;
int idx = 1;
foreach (var cr in crList)
{
if (!cr.StartDate.HasValue)
{
cr.StartDate = start;
}
if (cr.StartDate > DateTime.MinValue)
{
cr.StartDate = cr.StartDate.Value.AddDays(1);
}
if (cr.EndDate >= this.BewilligtStart && cr.StartDate <= this.BewilligtEnde)
{
var ez = new EntgeltzeitraumDigga();
ez.Index = idx++;
ez.Start = cr.StartDate.Value;
ez.Ende = cr.EndDate.Value;
if (ez.Start == DateTime.MinValue || ez.Start < BewilligtStart)
{
ez.Start = this.BewilligtStart;
}
if (ez.Ende == DateTime.MaxValue)
{
ez.Ende = this.BewilligtEnde;
}
ez.CostRatePeriod = cr;
ez.ServiceRecords = new List<ServiceRecordDC>();
ez.RateFactor = 0.20m; // Variabel setzen
Entgeltzeitraeume.Add(ez);
}
start = cr.EndDate.Value;
}
}
public virtual void CalculateMonatsbasisWerte(List<EntgeltzeitraumDigga> entgeltzeitraeume, CostBearer2SupportConcept cb2sc, IList<ServiceRecord> serviceRecords, DateTimeSpan span, Dictionary<string, BudgetnachweisDiggaMonatsZeile> monat2Zeile, DateTime monat)
{
while (monat <= this.BewilligtEnde)
{
String key = String.Format("{0:MM.yyyy}", monat);
var zeile = new BudgetnachweisDiggaMonatsZeile();
zeile.ServiceRecords = new List<ServiceRecordDC>();
zeile.Monat = monat;
zeile.SummeFLMinuten = 0;
zeile.SummeFehlkontakte = 0;
zeile.SummeGesamtMinutenMitFKGerundet = 0;
zeile.SummeGesamtStundenMitFKGerundet = 0;
foreach (var e in Entgeltzeitraeume)
{
if (e.Start <= monat && monat <= e.Ende)
{
zeile.Entgeltzeitraum = e.Index;
}
}
if (monat.Day != 1)
{
monat = new DateTime(monat.Year, monat.Month, 1);
}
monat = monat.AddMonths(1);
monat2Zeile.Add(key, zeile);
}
var groupBookingDict = new Dictionary<long, bool>();
foreach (var sr in serviceRecords)
{
if (sr.ServiceDescription.ServiceCategory.IsBillable && (!sr.GroupOid.HasValue || !groupBookingDict.ContainsKey(sr.GroupOid.Value)))
{
if (sr.GroupOid.HasValue)
{
groupBookingDict.Add(sr.GroupOid.Value, true);
}
var srDc = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(sr);
String key = String.Format("{0:MM.yyyy}", sr.Start);
if (monat2Zeile.ContainsKey(key))
{
if (monat2Zeile[key].Monat <= sr.Start.Value.Date)
{
monat2Zeile[key].ServiceRecords.Add(srDc);
decimal minuten = sr.RoundedDuration; // Check this
decimal prozent = sr.ServiceDescription.ServiceCategory.ProzentAbrechnung;
if (sr.ServiceDescription.Name.ToLower().Contains("fehlkontakt"))
{
monat2Zeile[key].SummeFehlkontakte += minuten;
}
else
{
monat2Zeile[key].SummeFLMinuten += minuten;
}
}
}
}
}
MonatsZeilen.AddRange(monat2Zeile.Values.OrderBy(m => m.Monat));
}
}
public class BudgetnachweisDiggaMonatsZeile
{
public List<ServiceRecordDC> ServiceRecords { get; set; }
public DateTime Monat { get; set; }
public decimal SummeFLMinuten { get; set; }
public decimal SummeFaktorMinuten { get; set; }
public decimal SummeMinutenGerundet { get; set; }
public decimal SummeFLStunden { get; set; }
public decimal SummeFehlkontakte { get; set; }
public decimal SummeFehlkontakteStunden { get; set; }
public decimal SummeGesamtMinutenMitFKGerundet { get; set; }
public decimal SummeGesamtStundenMitFKGerundet { get; set; }
public int Entgeltzeitraum { get; set; }
public decimal? Betrag { get; set; }
}
public class EntgeltzeitraumDigga
{
public List<ServiceRecordDC> ServiceRecords { get; set; }
public CostRatePeriodDC CostRatePeriod { get; set; }
public DateTime Start { get; set; }
public DateTime Ende { get; set; }
public decimal RateFactor { get; set; }
public decimal SummeFLMinuten { get; set; }
public decimal SummeFaktorMinuten { get; set; }
public decimal SummeMinutenGerundet { get; set; }
public decimal SummeFLStunden { get; set; }
public decimal SummeFehlkontakte { get; set; }
public decimal SummeFehlkontakteGerundet { get; set; }
public decimal SummeFehlkontakteStunden { get; set; }
public decimal SummeFaktorStunden { get; set; }
public decimal SummeGesamtStunden { get; set; }
public decimal SummeGesamtStundenMitFK { get; set; }
public int Index { get; set; }
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
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.Service.Invoicing
{
[IDSpecificClass(Identifier = "LWLDigga")]
public class LWLDiggaSettlementInvoiceCreation : SettlementInvoiceCreation
{
public override bool CanCreateInvoiceTheOldWay(Settlement2DC si, CostBearer2SupportConcept c2s)
{
return false;
}
public override void CreateInvoiceDetails(Settlement2DC si, CostBearer2SupportConcept cb2sc, DateTime? BewilligtStart, DateTime? BewilligtEnde)
{
// die gesamte Berechnung ist für Anhang zum Budgetnachweis und für die Berechnung der Rechnung identisch, daher in Extraklasse LWLDiggaBerechnnung gelagert
LWLDiggaBerechnung lwlCore = new LWLDiggaBerechnung();
lwlCore.CreateLWLDiggaBerechnung(si, cb2sc, BewilligtStart, BewilligtEnde);
var calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
var relDC = cb2sc.MapToNewDC();
CalculateSettlementInvoiceApprovedAmounts(si, relDC, calc);
var span = new DateTimeSpan();
span.StartDateTime = si.AccountingPeriodStart.Value;
span.EndDateTime = si.AccountingPeriodEnd.Value.AddDays(1).AddTicks(-1);
si.InvoiceItems = CreateInvoiceItemsForEntgeltzeitraeume(lwlCore.Entgeltzeitraeume);
CalculateAdvancedPayments(si, cb2sc);
CalculateEquityContribution(si, cb2sc.SupportConcept, BewilligtStart, BewilligtEnde);
CalculateSettlementInvoiceAmounts(si);
}
private List<InvoiceItemDC> CreateInvoiceItemsForEntgeltzeitraeume(List<EntgeltzeitraumDigga> Entgeltzeitraeume)
{
Dictionary<long, SupportConceptApprovalPeriodDC> oid2Scap = new Dictionary<long, SupportConceptApprovalPeriodDC>();
List<InvoiceItemDC> invoiceItems = new List<InvoiceItemDC>();
foreach (var e in Entgeltzeitraeume)
{
var iiList = CreateInvoiceItemsForAccountingPeriod(e);
invoiceItems.AddRange(iiList);
}
return invoiceItems;
}
private IList<InvoiceItemDC> CreateInvoiceItemsForAccountingPeriod(EntgeltzeitraumDigga e)
{
List<InvoiceItemDC> list = new List<InvoiceItemDC>();
if (e.SummeFLStunden > 0)
{
InvoiceItemDC ii = new InvoiceItemDC();
//ii.AccountingInterval = accountingPeriod.AccountingInterval;
ii.ItemPeriodStart = e.Start;
ii.ItemPeriodEnd = e.Ende;
ii.RateFactor = e.RateFactor;
ii.AmountPerUnit = e.CostRatePeriod.CostRateValue;
ii.ItemDescription = "Fachleistungsstunden";
ii.UnitCount = e.SummeFLStunden;
ii.AmountTotal = Math.Round(ii.UnitCount.Value * ii.AmountPerUnit.Value, 2, MidpointRounding.AwayFromZero);
ii.GrossAmountTotal = ii.AmountTotal;
//ii.MaxApprovedAmount = accountingPeriod.MaxApprovedAmount;
//ii.MaxApprovedUnitCount = accountingPeriod.MaxApprovedUnitCount;
//ii.ApprovedPerUnit = accountingPeriod.ApprovedPerUnit;
//ii.ApprovalUnit = accountingPeriod.ApprovalUnit;
list.Add(ii);
}
if (e.SummeFehlkontakteStunden > 0)
{
InvoiceItemDC iiF = new InvoiceItemDC();
//ii.AccountingInterval = accountingPeriod.AccountingInterval;
iiF.ItemPeriodStart = e.Start;
iiF.ItemPeriodEnd = e.Ende;
iiF.RateFactor = e.RateFactor;
iiF.AmountPerUnit = Math.Round(e.CostRatePeriod.CostRateValue.Value * 0.8m, 2, MidpointRounding.AwayFromZero); // Check auf Rundung
iiF.ItemDescription = "Fehlkontakte";
iiF.UnitCount = e.SummeFehlkontakteStunden;
iiF.AmountTotal = Math.Round(iiF.UnitCount.Value * iiF.AmountPerUnit.Value, 2, MidpointRounding.AwayFromZero);
iiF.GrossAmountTotal = iiF.AmountTotal;
//ii.MaxApprovedAmount = accountingPeriod.MaxApprovedAmount;
//ii.MaxApprovedUnitCount = accountingPeriod.MaxApprovedUnitCount;
//ii.ApprovedPerUnit = accountingPeriod.ApprovedPerUnit;
//ii.ApprovalUnit = accountingPeriod.ApprovalUnit;
list.Add(iiF);
}
return list;
}
}
}

View File

@@ -436,6 +436,8 @@
<Compile Include="Interfaces\IJsonMapper.cs" />
<Compile Include="Invoicing\ApprovalPeriod.cs" />
<Compile Include="Invoicing\GeneralInvoiceCreation.cs" />
<Compile Include="Invoicing\LWLDiggaBerechnung.cs" />
<Compile Include="Invoicing\LWLDiggaSettlementInvoiceCreation.cs" />
<Compile Include="Invoicing\SbdDefaultInvoiceCreation.cs" />
<Compile Include="Invoicing\EquityInvoiceCreation.cs" />
<Compile Include="Invoicing\InvoiceCreation.cs" />

View File

@@ -8,7 +8,7 @@ using BS.Shared.Extensions;
namespace BS.Shared.Services
{
// LWL: keinen RateFactor einrechnen
[IDSpecificClass(Identifiers = new string[] { "LWL", "LWLMaxAmount", "LWLNEU", "LWLBeWo67" })]
[IDSpecificClass(Identifiers = new string[] { "LWL", "LWLMaxAmount", "LWLNEU", "LWLBeWo67", "LWLDigga" })]
public class LWLCalculations : Calculations
{
public override decimal GetIntervalCountForDays(decimal totalDays, SupportConceptApprovalInterval interval)