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

This commit is contained in:
2024-09-11 14:35:08 +02:00
2 changed files with 143 additions and 189 deletions

View File

@@ -12,13 +12,11 @@ namespace CaritasverbandOstvest.Export
{
public override string CreateExportString(string pFileID, string[] pHeaderCaption, string[][] pContent)
{
if (pHeaderCaption != null && pHeaderCaption.Length > 0 && pHeaderCaption[0].Contains("Diamant"))
{
return DiamantExporter.CreateExportString(pHeaderCaption, pContent);
}
return base.CreateExportString(pFileID, pHeaderCaption, pContent);
}
public override QueryDC CreateQuery(QueryDC query)

View File

@@ -12,6 +12,8 @@ namespace CaritasverbandOstvest.Export
{
public class DiamantExporter
{
// DiamantExport ohne Relevanz der Rechnungspositionen, da Kostenstelle und Erlöskonto nur auf Kostenträger/Klientenebene festgelegt sind
// Abgrenzung für LWL und monatliche Rechnungen
public static QueryDC CreateQuery(QueryDC query)
{
@@ -39,19 +41,9 @@ namespace CaritasverbandOstvest.Export
}
}
if (query.Title == "Diamant Korrektur")
{
query.FileName = String.Format("005F{0:yyMM}.er2", dt);
query.QueryResult = GetKorrekturString(dt, customerOid);
}
else
{
query.FileName = String.Format("005F{0:yyyyMM}.er2", dt);
query.QueryResult = GetAbrechnungenString(dt, customerOid);
}
query.FileName = String.Format("005F{0:yyyyMM}.er2", dt);
query.QueryResult = GetAbrechnungenString(dt, customerOid);
}
return query;
}
@@ -66,53 +58,6 @@ namespace CaritasverbandOstvest.Export
return null;
}
private static string GetKorrekturString(DateTime dt, long? customerOid)
{
var exports = DAOFactory.GenericDAO.GetAllActive<BuchungsExport>();
foreach (var exp in exports)
{
if (exp.Name == "Diamant Export Buchungssätze")
{
if (exp.Parameter.Contains(String.Format("Monat={0:dd.MM.yyyy}", dt)))
{
return GetKorrekturString(exp, customerOid);
}
}
}
return "";
}
private static string GetKorrekturString(BuchungsExport exp, long? customerOid)
{
StringBuilder sb = new StringBuilder();
var lines = exp.Export.Split(new string[] {"F,0,005,,,AR,"}, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (!customerOid.HasValue)
{
sb.Append("F,0,005,,,AG,");
sb.Append(line);
}
else
{
var cust = DAOFactory.GenericDAO.LoadByID<Customer>(customerOid.Value);
String name = String.Format("{0}, {1}", cust.Person.LastName, cust.Person.FirstName);
String contains = String.Format("\"{0}\"", name);
if (line.Contains(contains))
{
sb.Append("F,0,005,,,AG,");
sb.Append(line);
}
}
}
return sb.ToString();
}
public static String GetDebitorenString(DateTime date)
{
var dt = ExecuteQuery(GetDebitorenSql(date), date);
@@ -154,165 +99,176 @@ namespace CaritasverbandOstvest.Export
public static String GetAbrechnungenString(DateTime date, long? customerOid)
{
StringBuilder sb = new StringBuilder();
var s = GetMonatlicheAbrechnungString(date, customerOid);
String sql;
sql = GetMonatlicheAbrechnungSql();
var dt = ExecuteQuery(sql, date);
var s = GetMonatlicheAbrechnungString(date, customerOid, dt);
if (!String.IsNullOrWhiteSpace(s))
{
sb.Append(s);
}
sql = GetMonatlicheErloeseLWLSql();
dt = ExecuteQuery(sql, date);
s = GetMonatlicheAbrechnungString(date, customerOid, dt);
if (!String.IsNullOrWhiteSpace(s))
{
sb.Append(s);
}
if (sb.Length > 0)
sb.AppendLine();
return sb.ToString();
}
public static String GetMonatlicheAbrechnungString(DateTime date, long? customerOid)
public static String GetMonatlicheAbrechnungString(DateTime date, long? customerOid, DataTable dt)
{
// Export enthält Rechnungsangaben Zeilen (Zeile F und hier auch Zeile G) und Kostenstellen/Rechnungspositionsangaben (Zeile K) in drei Zeilen
// Kommen aus Export in einer Zeile und könnten hier getrennt werden, derzeit nicht nötig (nur eine Kostenstelle u ein Erlöskonto pro Rechnung)
int startIdx = 1;
int stopIdx = 42; // ab da beginnen Angaben zu Kostenstelle -> zweite Zeile oder auch mehr falls mehrere Positionen
StringBuilder sb = new StringBuilder();
List<DataRow> mergedRows = new List<DataRow>();
Dictionary<string, DataRow> oid2Row = new Dictionary<string, DataRow>();
foreach (DataRow row in dt.Rows)
{
// Export enthält Rechnungsangaben Zeilen (Zeile F und hier auch Zeile G) und Kostenstellen/Rechnungspositionsangaben (Zeile K) in drei Zeilen
// Kommen aus Export in einer Zeile und werden hier getrennt, aber nur falls die Rechnung mehrere Positionen hat
int startIdx = 1;
int stopIdx = 34; // ab da beginnen Angaben zu Kostenstelle -> zweite Zeile oder auch mehr falls mehrere Positionen
String sql;
sql = GetMonatlicheAbrechnungSql();
var dt = ExecuteQuery(sql, date);
string oid = row[0].ToString();
bool storno = false;
StringBuilder sb = new StringBuilder();
List<DataRow> mergedRows = new List<DataRow>();
Dictionary<string, DataRow> oid2Row = new Dictionary<string, DataRow>();
foreach (DataRow row in dt.Rows)
if (!oid2Row.ContainsKey(oid))
{
string oid = row[0].ToString();
bool storno = false;
oid2Row.Add(oid, row);
if (!oid2Row.ContainsKey(oid))
if (sb.Length > 0)
{
oid2Row.Add(oid, row);
sb.AppendLine();
}
if (sb.Length > 0)
for (int i = startIdx; i < row.ItemArray.Length; i++)
{
var item = row[i];
if (i == 15 || i == 40 || i == 50 )
{
sb.Append(String.Format("{0}", item.ToString().Replace(",", ".")));
sb.Append(";");
}
else if (i == 16 || i == 41)
{
sb.Append('"');
sb.Append(item);
sb.Append('"');
}
else if (i == 34) //Zeilenumbruch für Erlöskontozeile
{
sb.Append(item);
sb.AppendLine();
}
for (int i = startIdx; i < row.ItemArray.Length; i++)
else if (i == 37)
{
var item = row[i];
if (i == 15 || i == 42)
var position = item.ToString();
if (position.ToLower().Contains("selbstzahler"))
{
sb.Append(String.Format("{0}", item.ToString().Replace(",", ".")));
sb.Append(";");
}
else if (i == 16)
{
sb.Append('"');
sb.Append(item);
sb.Append('"');
}
else if (i == stopIdx)
{
sb.AppendLine();
sb.Append(item);
sb.Append(";");
}
else if (i == 12 || i == 44)
{
string konto = SetKonto(item);
sb.Append(String.Format("{0}", konto));
sb.Append(";");
}
else if (i == 36)
{
var position = item.ToString();
if (position.ToLower().Contains("ufh") || position.ToLower().Contains("kasse"))
{
sb.Append("20072;");
}
else
{
sb.Append("20002;");
}
sb.Append("40721;");
}
else
{
sb.Append(item);
sb.Append(";");
sb.Append("46914;");
}
}
}
else
{
if (sb.Length > 0)
else if (i == stopIdx)
{
sb.AppendLine();
sb.Append(item);
sb.Append(";");
}
for (int i = startIdx; i < row.ItemArray.Length; i++)
else
{
var item = row[i];
// mach nichts mit den ersten Spalten -> erstelle nur Kostenstellen
if (i == stopIdx)
{
sb.Append(item);
sb.Append(";");
}
else if (i == 42)
{
sb.Append(String.Format("{0}", item.ToString().Replace(",", ".")));
sb.Append(";");
}
else if (i == 36)
{
var position = item.ToString();
if (position.ToLower().Contains("ufh") || position.ToLower().Contains("kasse"))
{
sb.Append("20072;");
}
else
{
sb.Append("20002;");
}
}
else if (i == 44)
{
string konto = SetKonto(item);
sb.Append(String.Format("{0}", konto));
sb.Append(";");
}
else if (i > stopIdx)
{
sb.Append(item);
sb.Append(";");
}
sb.Append(item);
sb.Append(";");
}
}
}
return sb.ToString();
}
return sb.ToString();
}
private static string SetKonto(object item)
private static string GetMonatlicheErloeseLWLSql()
{
string konto = "84290"; // Default SPFH Kreis
if (item != null)
{
if (item.ToString().ToLower().Contains("spfh") && item.ToString().ToLower().Contains("stadt"))
{
konto = "84291";
}
else if (item.ToString().ToLower().Contains("ufh") && item.ToString().ToLower().Contains("aok")) //derzeit nur ein Einzelfall
{
konto = "84281";
}
else if (item.ToString().ToLower().Contains("ufh") && item.ToString().ToLower().Contains("selbstzahler"))
{
konto = "84283";
}
if (item.ToString().ToLower().Contains("ufh")) // Standard für UFH
{
konto = "84282";
}
}
return konto;
String sql = @"
SELECT
CONCAT(qry.Oid, sum(qry.Betrag)) AS OID,
'F',
'0',
'00305',
null,
null,
'AR',
':Abrechnungsmonat',
':Periode',
null,
':Abrechnungsmonat' AS InvoiceNumber,
qry.DebitorNumber,
null,
'-1',
null,
sum(qry.Betrag) AS 'Betrag',
qry.Verwendung,
null, null, null, 'EUR',
null, null, null, null, null, null, null, null, null, null, null, null, null, 'E',
'G', 0, qry.Name, '-1', null, Round(sum(qry.Betrag) * -1, 2), qry.Verwendung as 'Verwendung',
'K', 0, '231200' AS Kostenstelle, null, null, null, null, null, Round(sum(qry.Betrag) * -1, 2)
FROM
(
(SELECT
IF(crpRateFactor.`CostRateValue` is null, ROUND((sr.`GeleisteteFLM` / 60) * (SELECT crp.`CostRateValue` FROM `costrateperiod` crp WHERE crp.`ObjectTid` = 22 AND crp.`CostRateType` = 0 AND crp.`ObjectOid` = cb2sc.`CostBearerOid` AND (crp.`EndDate` is null or crp.`EndDate` > ':Monat_Start') order by IF(crp.`EndDate` is null, MAKEDATE(9999,365),crp.`EndDate`) LIMIT 1 )),
ROUND(ROUND((sr.`GeleisteteFLM` / 60), 2) * (SELECT crp.`CostRateValue` FROM `costrateperiod` crp WHERE crp.`ObjectTid` = 22 AND crp.`CostRateType` = 0 AND crp.`ObjectOid` = cb2sc.`CostBearerOid` AND (crp.`EndDate` is null or crp.`EndDate` > ':Monat_Start') order by IF(crp.`EndDate` is null, MAKEDATE(9999,365),crp.`EndDate`) LIMIT 1 ) * ((100 + crpRateFactor.`CostRateValue`)/100), 2)) AS 'Betrag',
c.DebitorNumber,
org.Name,
CONCAT(org.Name,', ', p.`LastName`, ', ', p.`FirstName`) as 'Verwendung',
cb2sc.Oid
FROM `supportconcept` sc
INNER JOIN `costbearer2supportconcept` cb2sc ON sc.`Oid` = cb2sc.`SupportConceptOid`
INNER JOIN `costbearer` cb ON cb2sc.`CostBearerOid` = cb.`Oid`
LEFT JOIN
(SELECT crp.`ObjectOid`, crp.`CostRateValue` FROM `costrateperiod` crp
WHERE crp.`ObjectTid` = 22 AND crp.`CostRateType` = 2 AND (crp.`EndDate` is null or crp.`EndDate` > NOW()))
AS crpRateFactor ON crpRateFactor.`ObjectOid` = 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`
LEFT JOIN
(SELECT sr2.`CostBearer2SupportConceptOid`, SUM(sr2.`roundedduration` / IF(sr2.`GroupEmployeeCount` is null, 1, sr2.`GroupEmployeeCount`)) AS GeleisteteFLM FROM `servicerecord` sr2
INNER JOIN `servicedescription` sd ON sr2.`ServiceDescriptionOid` = sd.`Oid`
INNER JOIN `servicecategory` sc ON sd.`ServiceCategoryOid` = sc.`Oid`
WHERE sr2.`StartDate` >= ':Monat_Start' AND sr2.`StartDate` < ':Monat_End' AND sc.`Billable` = 1 and sd.Name <> 'Ausfallzeit' GROUP BY sr2.`CostBearer2SupportConceptOid`)
AS sr ON sr.`CostBearer2SupportConceptOid` = cb2sc.`Oid`
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 AND org.Name = 'LWL' AND (sr.`GeleisteteFLM` is not null))
UNION
(SELECT
ROUND(0.8 * (sr.`GeleisteteFLM` / 60) * (SELECT crp.`CostRateValue` FROM `costrateperiod` crp WHERE crp.`ObjectTid` = 22 AND crp.`CostRateType` = 0 AND crp.`ObjectOid` = cb2sc.`CostBearerOid` AND (crp.`EndDate` is null or crp.`EndDate` > ':Monat_Start') order by IF(crp.`EndDate` is null, MAKEDATE(9999,365),crp.`EndDate`) LIMIT 1 )) AS 'Betrag',
c.DebitorNumber,
org.Name,
CONCAT(org.Name,', ', p.`LastName`, ', ', p.`FirstName`) as 'Verwendung',
cb2sc.Oid
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`
LEFT JOIN
(SELECT sr2.`CostBearer2SupportConceptOid`, SUM(sr2.`roundedduration` / IF(sr2.`GroupEmployeeCount` is null, 1, sr2.`GroupEmployeeCount`)) AS GeleisteteFLM FROM `servicerecord` sr2
INNER JOIN `servicedescription` sd ON sr2.`ServiceDescriptionOid` = sd.`Oid`
INNER JOIN `servicecategory` sc ON sd.`ServiceCategoryOid` = sc.`Oid`
WHERE sr2.`StartDate` >= ':Monat_Start' AND sr2.`StartDate` < ':Monat_End' AND sc.`Billable` = 1 and sd.Name = 'Ausfallzeit' GROUP BY sr2.`CostBearer2SupportConceptOid`)
AS sr ON sr.`CostBearer2SupportConceptOid` = cb2sc.`Oid`
WHERE c.`IsActive` = 1 AND sc.`IsActive` = 1 AND org.Name = 'LWL' AND (sr.`GeleisteteFLM` is not null))
)qry
GROUP BY qry.OID
ORDER BY qry.Verwendung
";
return sql;
}
private static String GetDebitorenSql(DateTime date)
@@ -371,7 +327,7 @@ SELECT
CONCAT(cb2sc.Oid, ib.InvoiceNumber, Round(sip.Claim, 0)) AS OID,
'F',
'0',
'99',
'00305',
null,
null,
'AR',
@@ -380,14 +336,15 @@ null,
null,
ib.InvoiceNumber,
c.DebitorNumber,
CONCAT(ii.ItemDescription, ' ', org.Name),
null,
'-1',
null,
Round(sip.Claim, 2) AS 'Betrag',
CONCAT('Re. ', p.`LastName`, ', ', p.`FirstName`) as 'Verwendung',
CONCAT(p.`LastName`, ', ', p.`FirstName`) as 'Verwendung',
null, null, null, 'EUR',
null, null, null, '14', null, null, null, null, null, null, null, null, null,
'K', 0, ii.ItemDescription, null, 'V', null, null, null, Round(ii.AmountTotal * -1, 2), null, CONCAT(ii.ItemDescription, ' ', org.Name), null, null, null, null, null, null
null, null, null, ':Zahlungsziel', null, null, null, null, null, null, null, null, null, 'E',
'G', 0, org.Name, '-1', null, Round(sip.Claim * -1, 2), CONCAT(p.`LastName`, ', ', p.`FirstName`) as 'Verwendung',
'K', 0, '231200' AS Kostenstelle, null, null, null, null, null, Round(sip.Claim * -1, 2)
FROM
person p
INNER JOIN customer c on c.personoid = p.oid
@@ -398,10 +355,8 @@ null, null, null, '14', null, null, null, null, null, null, null, null, null,
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.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodStart` < ':Monat_End'
ORDER BY ib.invoicenumber
";
return sql;
@@ -413,6 +368,7 @@ ORDER BY ib.invoicenumber
newsql = newsql.Replace(":PeriodeSlash", String.Format("{0:MM/yyyy}", dt));
newsql = newsql.Replace(":Periode", String.Format("{0:MMyyyy}", dt));
newsql = newsql.Replace(":Abrechnungsmonat", String.Format("{0:ddMMyyyy}", dt));
newsql = newsql.Replace(":Zahlungsziel", String.Format("{0:ddMMyy}", dt.AddDays(30)));
newsql = newsql.Replace(":Monat_Start", String.Format("{0:yyyy-MM}-01", dt));
dt = dt.AddMonths(1);
newsql = newsql.Replace(":Monat_End", String.Format("{0:yyyy-MM}-01", dt));