Merge branch 'master' of ssh://float.ownsoft.de/git/beyondSoft/BeWo

This commit is contained in:
2024-08-19 07:41:42 +02:00
5 changed files with 364 additions and 51 deletions

View File

@@ -28,17 +28,12 @@ namespace AwoDortmund.Export
if (pHeaderCaption != null && pHeaderCaption.Length > 1 && pHeaderCaption[0].Contains("Diamant"))
{
DateTime dt = DateTime.Now;
DateTime.TryParse(pHeaderCaption[1], out dt);
return GetAbrechnungenString(dt);
}
}
return null;
}
public static String GetAbrechnungenString(DateTime date)
{
StringBuilder sb = new StringBuilder();
@@ -50,32 +45,262 @@ namespace AwoDortmund.Export
if (sb.Length > 0)
sb.AppendLine();
//s = GetAbschlagszahlungenString(date);
//if (!String.IsNullOrWhiteSpace(s))
//{
// sb.Append(s);
//}
//if (sb.Length > 0)
// sb.AppendLine();
s = GetMonatlicheAbrechnungKrankenkassenString(date);
if (!String.IsNullOrWhiteSpace(s))
{
sb.Append(s);
}
if (sb.Length > 0)
{
sb.AppendLine();
}
//s = GetSelbstzahlerString(date);
//if (!String.IsNullOrWhiteSpace(s))
//{
// sb.Append(s);
//}
return sb.ToString();
}
public static String GetMonatlicheAbrechnungKrankenkassenString(DateTime date)
{
// Export enthält Rechnungsangaben Zeilen (Zeile F) und Kostenstellen/Rechnungspositionsangaben (Zeile K) in zwei Zeilen
// Kommen aus Export in einer Zeile und werden hier getrennt, falls die Rechnung mehrere Positionen hat
int startIdx = 1;
int stopIdx1 = 35;
int stopIdx2 = 43; // ab da beginnen Angaben zu Kostenstelle -> zweite Zeile oder auch mehr falls mehrere Positionen
String sql;
sql = GetMonatlicheAbrechnungenSqlNeu();
var dt = ExecuteQuery(sql, date);
StringBuilder sb = new StringBuilder();
List<DataRow> mergedRows = new List<DataRow>();
Dictionary<string, DataRow> oid2Row = new Dictionary<string, DataRow>();
foreach (DataRow row in dt.Rows)
{
string oid = row[0].ToString();
bool storno = false;
if (!oid2Row.ContainsKey(oid))
{
oid2Row.Add(oid, row);
if (sb.Length > 0)
{
sb.AppendLine();
}
for (int i = startIdx; i < row.ItemArray.Length; i++)
{
var item = row[i];
if (i == 15)
{
decimal betrag = ErzeugeBetrag(item);
if (betrag != 0)
{
if (betrag < 0)
{
storno = true;
}
sb.Append(String.Format("{0:0.00}", betrag));
sb.Append(";");
}
}
else if (i == 16)
{
sb.Append('"');
sb.Append(item);
sb.Append('"');
}
else if (i == stopIdx1)
{
sb.AppendLine();
sb.Append(item);
sb.Append(";");
}
else if (i == 40)
{
decimal betrag = ErzeugeBetrag(item);
if (betrag != 0)
{
sb.Append(String.Format("{0:0.00}", betrag * -1).Replace(",", "."));
sb.Append(";");
}
}
else if (i == 41)
{
sb.Append('"');
sb.Append(item);
sb.Append('"');
}
else if (i == stopIdx2)
{
sb.AppendLine();
sb.Append(item);
sb.Append(";");
}
else if (i == 51)
{
decimal betrag = ErzeugeBetrag(item);
if (betrag != 0)
{
sb.Append(String.Format("{0:0.00}", betrag * -1).Replace(",", "."));
sb.Append(";");
}
}
else if (i == 45)
{
var position = item.ToString();
if (position.Contains("Wohngruppenzuschlag") || position.Contains("Assistenz"))
{
sb.Append("610915;");
}
else
{
sb.Append("610905;");
}
}
else
{
sb.Append(item);
sb.Append(";");
}
}
}
else
{
if (sb.Length > 0)
{
sb.AppendLine();
}
for (int i = startIdx; i < row.ItemArray.Length; i++)
{
var item = row[i];
// mach nichts mit den ersten Spalten -> erstelle nur Kostenstellen
if (i == stopIdx2)
{
sb.AppendLine();
sb.Append(item);
sb.Append(";");
}
else if (i == 51)
{
decimal betrag = ErzeugeBetrag(item);
if (betrag != 0)
{
sb.Append(String.Format("{0:0.00}", betrag * -1).Replace(",", "."));
sb.Append(";");
}
}
else if (i == 45)
{
var position = item.ToString();
if (position.Contains("Wohngruppenzuschlag") || position.Contains("Assistenz"))
{
sb.Append("610915;");
}
else
{
sb.Append("610905;");
}
}
else if (i > stopIdx2)
{
sb.Append(item);
sb.Append(";");
}
}
}
}
return sb.ToString();
}
private static Dictionary<long, decimal> CreateDictionaryKrankenkassen(DataTable dt)
{
Dictionary<long, decimal> dict = new Dictionary<long, decimal>();
if (dt != null)
{
foreach (DataRow row in dt.Rows)
{
long? oid = row.ItemArray[0] as long?;
decimal? betrag = row.ItemArray[4] as decimal?;
if (oid.HasValue && betrag.HasValue)
{
dict.Add(oid.Value, betrag.Value);
}
}
}
return dict;
}
public static decimal ErzeugeBetrag(object betragObj)
{
decimal gesamtbetrag = 0;
if (betragObj != null)
{
Decimal.TryParse(betragObj.ToString().Replace(".", ","), out gesamtbetrag);
}
decimal betrag = Math.Round(gesamtbetrag, 2, MidpointRounding.AwayFromZero);
return betrag;
}
private static String GetMonatlicheAbrechnungenSqlNeu()
{
String sql = @"
SELECT
CONCAT(cb2sc.Oid, ib.InvoiceNumber, Round(sip.Claim, 0)) AS OID,
'F',
'0',
'114',
null,
'BEWO',
'AR',
':Abrechnungsmonat',
':Periode',
null,
ib.InvoiceNumber,
c.DebitorNumber,
null,
null,
null,
Round(sip.Claim, 2) AS 'Betrag',
CONCAT(p.`LastName`, ', ', p.`FirstName`, ' ', IF(cb2sc.CustomerRefenrenceNumber is null, '', cb2sc.CustomerRefenrenceNumber), ' Abrechnung :PeriodePunkt ', org.Name) as 'Verwendung',
null, null, null, 'EUR',
null, null, null, null, null, null, null, null, null, null, null, null, null, null,
'G', '0', '49100000', null, null,
Round(sip.Claim * -1, 2) AS 'Betrag2',
CONCAT(p.`LastName`, ', ', p.`FirstName`, ' ', IF(cb2sc.CustomerRefenrenceNumber is null, '', cb2sc.CustomerRefenrenceNumber), ' Abrechnung :PeriodePunkt ', org.Name) as 'Verwendung2', null,
'K', 0, ii.ItemDescription, null, null, null, null, null, ii.AmountTotal
FROM
person p
INNER JOIN customer c on c.personoid = p.oid
INNER JOIN supportconcept sc on sc.customeroid = c.oid
INNER JOIN costbearer2supportconcept cb2sc on cb2sc.supportconceptoid = sc.oid
INNER JOIN costbearer cb on cb2sc.costbeareroid = cb.oid
INNER JOIN organisation org on org.costbeareroid = cb.oid
INNER JOIN invoicebase ib on ib.costbearer2supportconceptoid = cb2sc.oid
INNER JOIN serviceinvoice si on si.invoicebaseoid = ib.oid
INNER JOIN serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid
INNER JOIN invoiceitem ii on ii.ServiceInvoicePeriodOid = sip.oid
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 and ib.type <> 1 and ib.InvoiceId = 'RechnungSoziotherapie'
and ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End'
ORDER BY ib.invoicenumber
";
return sql;
}
public static String GetMonatlicheAbrechnungLvrString(DateTime date)
{
int startIdx = 0;
DataTable dtAssi = null;
DataTable dtZuschlag = null;
DataTable dtOffenerTreff = null;
DataTable dtSoziTreff = null;
String sql;
if (date < new DateTime(2019, 1, 1))
{
sql = GetMonatlicheAbrechnungLvrSqlAlt(date);
@@ -86,9 +311,10 @@ namespace AwoDortmund.Export
sql = GetMonatlicheAbrechnungLvrSqlNeu(date);
List<long> cats = new List<long>();
cats.Add(33); // Assistenzleistung
cats.Add(38); // Assistenzleistung
var assiSql = GetMonatlicheAbrechnungStringForCatsSql(date, cats, null);
cats.Add(33); // Assistenzleistung nach § 45 b SGB XI
cats.Add(49); // Assistenzleistung
cats.Add(54); // Assistenzleistung nach § 45 a SGB XI
var assiSql = GetMonatlicheAbrechnungStringForCatsSql(date, cats, null); // erstellt monatliche Abgrenzung und zieht daraus die Teilbeträge
dtAssi = ExecuteQuery(assiSql, date);
cats = new List<long>();
@@ -96,17 +322,22 @@ namespace AwoDortmund.Export
var otSql = GetMonatlicheAbrechnungStringForCatsSql(date, cats, null);
dtOffenerTreff = ExecuteQuery(otSql, date);
cats = new List<long>();
cats.Add(50); // Soziotherapie
var soziSql = GetMonatlicheAbrechnungStringForCatsSql(date, cats, null);
dtSoziTreff = ExecuteQuery(soziSql, date);
//cats = new List<long>();
//cats.Add(50); // Soziotherapie
//var soziSql = GetMonatlicheAbrechnungStringForCatsSql(date, cats, null);
//dtSoziTreff = ExecuteQuery(soziSql, date);
//// cats.Add(38); Wohngruppenzuschlag nach §38a SGB11
//var zuschlagSql = GetMonatlicheZuschlaegeStringSql(date); // hier gehts nur über die InvoiceItems
//dtZuschlag = ExecuteQuery(zuschlagSql, date);
}
var dt = ExecuteQuery(sql, date);
Dictionary<long, decimal> c2sOid2AssiBetrag = CreateDictionary(dtAssi);
Dictionary<long, decimal> c2sOid2OtBetrag = CreateDictionary(dtOffenerTreff);
Dictionary<long, decimal> c2sOid2SoziBetrag = CreateDictionary(dtSoziTreff);
//Dictionary<long, decimal> c2sOid2SoziBetrag = CreateDictionary(dtSoziTreff);
//Dictionary<long, decimal> c2sOid2ZuschlagBetrag = CreateDictionary(dtZuschlag);
StringBuilder sb = new StringBuilder();
@@ -122,7 +353,7 @@ namespace AwoDortmund.Export
mergedRows.Add(row);
}
//Nach Änderung der Rechnungslogik - Aushebeln des Merge für Soziotherapie und verwandte Leistungen
else if (oid2Row.ContainsKey(oid) && (c2sOid2AssiBetrag.ContainsKey(oid) || c2sOid2SoziBetrag.ContainsKey(oid)))
else if (oid2Row.ContainsKey(oid) && c2sOid2AssiBetrag.ContainsKey(oid))
{
mergedRows.Add(row);
}
@@ -179,7 +410,7 @@ namespace AwoDortmund.Export
}
else
{
ErstelleKostenstellenZeilenNeu(row, sb, c2sOid2AssiBetrag, c2sOid2OtBetrag, c2sOid2SoziBetrag);
ErstelleKostenstellenZeilenNeu(row, sb, c2sOid2AssiBetrag, c2sOid2OtBetrag);
}
}
//F,0,050,,BEWO,DA,01012016,012016,iBelegNr1,Belegnr1,220001,,,,999.99, "Name AZ Abrechnung 01/2016 LVR",,,EUR,,,,,,,,,,,R,,,
@@ -201,7 +432,11 @@ namespace AwoDortmund.Export
if (oid.HasValue && betrag.HasValue)
{
dict.Add(oid.Value, betrag.Value);
if (!dict.ContainsKey(oid.Value))
{
dict.Add(oid.Value, betrag.Value);
}
dict[oid.Value] += betrag.Value;
}
}
}
@@ -239,7 +474,7 @@ namespace AwoDortmund.Export
}
}
private static void ErstelleKostenstellenZeilenNeu(DataRow row, StringBuilder sb, Dictionary<long, decimal> c2sOid2AssiBetrag, Dictionary<long, decimal> c2sOid2OtBetrag, Dictionary<long, decimal> c2sOid2SoziBetrag)
private static void ErstelleKostenstellenZeilenNeu(DataRow row, StringBuilder sb, Dictionary<long, decimal> c2sOid2AssiBetrag, Dictionary<long, decimal> c2sOid2OtBetrag)
{
if (row.ItemArray.Length > 15)
{
@@ -255,7 +490,6 @@ namespace AwoDortmund.Export
decimal betragBewo = Math.Round(gesamtbetrag, 2, MidpointRounding.AwayFromZero);
decimal betragGruppen = 0;//Math.Round(gesamtbetrag, 2, MidpointRounding.AwayFromZero);
decimal betragAssistenz = 0;//Math.Round(gesamtbetrag, 2, MidpointRounding.AwayFromZero);
decimal betragSozi = 0;
if (oid.HasValue && c2sOid2AssiBetrag.ContainsKey(oid.Value))
{
@@ -263,19 +497,13 @@ namespace AwoDortmund.Export
betragAssistenz = Math.Round(betragAssistenz, 2, MidpointRounding.AwayFromZero);
betragBewo -= betragAssistenz;
}
if (oid.HasValue && c2sOid2OtBetrag.ContainsKey(oid.Value))
{
betragGruppen = c2sOid2OtBetrag[oid.Value];
betragGruppen = Math.Round(betragGruppen, 2, MidpointRounding.AwayFromZero);
betragBewo -= betragGruppen;
}
if (oid.HasValue && c2sOid2SoziBetrag.ContainsKey(oid.Value))
{
betragSozi = c2sOid2SoziBetrag[oid.Value]; //SoziotherapieRechnung enthält nur Soziotherapiebeträge
betragSozi = Math.Round(betragBewo, 2, MidpointRounding.AwayFromZero);
betragBewo = 0;
}
//bewo 610900
//offener Treff 610910 Leistungskategorie Gruppenbuchung
//Assistenzleistungen 610915 Leistungskategorien Assistenz (Kategorie Assistenzleistungen)
@@ -299,7 +527,6 @@ namespace AwoDortmund.Export
sb.Append(String.Format("{0:0.##}", betragGruppen * -1).Replace(",", "."));
sb.Append(";");
}
if (betragAssistenz > 0)
{
sb.AppendLine();
@@ -307,14 +534,21 @@ namespace AwoDortmund.Export
sb.Append(String.Format("{0:0.##}", betragAssistenz * -1).Replace(",", "."));
sb.Append(";");
}
//if (betragZuschlag > 0)
//{
// sb.AppendLine();
// sb.Append("K;0;610915;;;;;;");
// sb.Append(String.Format("{0:0.##}", betragZuschlag * -1).Replace(",", "."));
// sb.Append(";");
//}
if (betragSozi > 0)
{
sb.AppendLine();
sb.Append("K;0;610905;;;;;;");
sb.Append(String.Format("{0:0.##}", betragSozi * -1).Replace(",", "."));
sb.Append(";");
}
//if (betragSozi > 0)
//{
// sb.AppendLine();
// sb.Append("K;0;610905;;;;;;");
// sb.Append(String.Format("{0:0.##}", betragSozi * -1).Replace(",", "."));
// sb.Append(";");
//}
}
}
@@ -529,7 +763,7 @@ INNER JOIN `person` p on c.`PersonOid` = p.`Oid`
INNER JOIN invoicebase ib on ib.costbearer2supportconceptoid = cb2sc.oid
inner join serviceinvoice si on si.invoicebaseoid = ib.oid
inner join serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 and ib.type <> 1
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 and ib.type <> 1 and ib.InvoiceId <> 'RechnungSoziotherapie'
and ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End'
ORDER BY p.`LastName`, p.`FirstName`, cb2sc.`ApprovedStartDate`
";
@@ -764,6 +998,37 @@ ORDER BY p.`LastName`
return sql;
}
private static String GetMonatlicheZuschlaegeStringSql(DateTime dt)
{
String sql = @"
SELECT
cb2sc.oid,
c.oid,
sc.oid,
ib.InvoiceNumber,
c.DebitorNumber,
Round(ii.AmountTotal, 2) AS 'Forderung',
'1' as 'PauschalerFaktor',
ii.UnitCount AS`GeleisteteFLM`
FROM `supportconcept` sc
INNER JOIN `costbearer2supportconcept` cb2sc ON sc.`Oid` = cb2sc.`SupportConceptOid`
INNER JOIN `costbearer` cb ON cb2sc.`CostBearerOid` = cb.`Oid`
INNER JOIN `organisation` org ON org.`CostBearerOid` = cb.`Oid`
INNER JOIN `customer` c ON sc.`CustomerOid` = c.`Oid`
INNER JOIN `person` p on c.`PersonOid` = p.`Oid`
INNER JOIN invoicebase ib on ib.costbearer2supportconceptoid = cb2sc.oid
inner join serviceinvoice si on si.invoicebaseoid = ib.oid
inner join serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid
inner join invoiceitem ii on ii.serviceinvoiceperiodoid = sip.oid
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 and ib.isactive = 1 and ib.type <> 1 and ii.ItemDescription like 'Wohngruppenzuschlag%'
and ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End'
ORDER BY p.`LastName`, p.`FirstName`, cb2sc.`ApprovedStartDate`
";
return sql;
}
public static DataTable ExecuteQuery(String sql, DateTime dt)
{
var newsql = sql;

View File

@@ -71,6 +71,8 @@
</Compile>
<Compile Include="Export\CustomDataExporter.cs" />
<Compile Include="Export\SimbaExporter.cs" />
<Compile Include="Invoicing\CustomInvoiceFactory.cs" />
<Compile Include="Invoicing\DefaultInvoiceCreation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceInvoiceReport.cs">
<SubType>Component</SubType>

View File

@@ -53,6 +53,9 @@ namespace ChristopherusHausFamilienhilfe.Export
{
sb.AppendLine();
}
DateTime lastDate = new DateTime(date.Year, date.Month, 1);
lastDate = lastDate.AddMonths(1).AddDays(-1);
sb.Append(String.Format("\"{0}\"", row[0]));
sb.Append(";");
sb.Append(String.Format("{0:0.00}", row[1]));
@@ -61,7 +64,8 @@ namespace ChristopherusHausFamilienhilfe.Export
sb.Append(";");
sb.Append(String.Format("{0}", row[3]));
sb.Append(";;");
sb.Append(String.Format("{0:ddMMyyyy}", row[4]));
sb.Append(String.Format("{0:dd.MM.yyyy}", lastDate)); //Simba nimmt nur Buchungen an, ReDatum = Abrechnungszeitraum
//sb.Append(String.Format("{0:ddMMyyyy}", row[4]));
sb.Append(";;");
sb.Append(String.Format("{0}", row[5]));
sb.Append(";");

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using BeWo.Service.Invoicing;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
namespace ChristopherusHausFamilienhilfe.Invoicing
{
public class CustomInvoiceFactory : InvoiceFactory
{
public override InvoiceCreation CreateInvoiceCreator(string specificId, string tenant, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
return new DefaultInvoiceCreation();
}
}
}

View File

@@ -0,0 +1,26 @@
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 BeWo.Service.Plugins;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
namespace ChristopherusHausFamilienhilfe.Invoicing
{
public class DefaultInvoiceCreation : InvoiceCreation
{
public override void SetInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer, DateTimeSpan invoicePeriod, IList<CompactSupportConceptDC> supportConceptList)
{
base.SetInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConceptList);
invoice.InvoiceBase.InvoiceDate = invoice.InvoiceBase.AccountingPeriodEnd;
}
}
}