Files
BeWoPlaner/ReportImp/Humanitas/Export/DatevExporter.cs
Christian 9c97d6fe79 CB Merge
2019-07-12 17:36:37 +02:00

410 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BS.Shared.DataContracts;
using DevExpress.Data;
namespace Humanitas.Export
{
public class DatevExporter
{
public static QueryDC CreateQuery(QueryDC query)
{
DateTime dt = DateTime.Now;
DateTime.TryParse(query.Parameter[0].Value.ToString(), out dt);
query.FileName = String.Format("Export{0:yyyyMM}.csv", dt);
query.QueryResult = GetAbrechnungenString(dt);
return query;
}
public static string CreateExportString(string[] pHeaderCaption, string[][] pContent)
{
if (pHeaderCaption != null && pHeaderCaption.Length > 1 && pHeaderCaption[0].Contains("Datev"))
{
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();
var s = GetMonatlicheAbrechnungString(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 GetMonatlicheAbrechnungString(DateTime date)
{
var dt = ExecuteQuery(GetMonatlicheAbrechnungSql(date), date);
ResultDataRow row1 = new ResultDataRow();
ResultDataRow row2 = new ResultDataRow();
ResultDataRow row3 = new ResultDataRow();
ResultDataRow row4 = new ResultDataRow();
ResultDataRow row5 = new ResultDataRow();
ResultDataRow row6 = new ResultDataRow();
ResultDataRow row7 = new ResultDataRow();
ResultDataRow row8 = new ResultDataRow();
row1.Posten = "Leistungen abgerechnet (Spitzabrechnung oder andere Rechnung ist gestellt)";
row2.Posten = "Leistungen abgerechnet (Spitzabrechnung oder andere Rechnung ist gestellt)";
row3.Posten = "Geleistete Fachleistungsstunden";
row4.Posten = "Geleistete Fachleistungsstunden";
row5.Posten = "Geleistete Fachleistungsstunden";
row6.Posten = "Geleistete Fachleistungsstunden";
row7.Posten = "Geleistete Fachleistungsstunden";
row8.Posten = "Geleistete Fachleistungsstunden";
row1.Typ = "bewilligt";
row2.Typ = "bewilligt";
row3.Typ = "bewilligt";
row4.Typ = "bewilligt";
row5.Typ = "noch nicht bewilligt";
row6.Typ = "noch nicht bewilligt";
row7.Typ = "noch nicht bewilligt";
row8.Typ = "noch nicht bewilligt";
row1.Untertyp = "bezahlt";
row2.Untertyp = "noch nicht bezahlt";
row3.Untertyp = "noch nicht abgerechnet (monatl. Abschlagszahlungen kommen vom LVR und Stadt Düsseldorf)";
row4.Untertyp = "noch nicht abgerechnet (keine Abschlagszahlungen bei Jugendamt oder Sonstigen)";
row5.Untertyp = "Folgeantrag (Klient war schon bewilligt) beim Kostenträger eingereicht und in Klärung";
row6.Untertyp = "Folgeantrag (Klient war schon bewilligt) in Bearbeitung";
row7.Untertyp = "Erstantrag (Klient war noch nicht bewilligt) beim Kostenträger eingereicht und in Klärung";
row8.Untertyp = "Erstantrag (Klient war noch nicht bewilligt) in Bearbeitung";
row1.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row2.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row3.Kostentraeger = "LVR, Stadt Düsseldorf";
row4.Kostentraeger = "Jugendamt (JA), Sonstige";
row5.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row6.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row7.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row8.Kostentraeger = "LVR, Jugendamt, Stadt Düsseldorf, Sonstige";
row1.Datum = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
row2.Datum = row1.Datum;
row3.Datum = row1.Datum;
row4.Datum = row1.Datum;
row5.Datum = row1.Datum;
row6.Datum = row1.Datum;
row7.Datum = row1.Datum;
row8.Datum = row1.Datum;
//org.Oid,
//org.Name,
//c.Oid,
//c.DebitorNumber as 'Konto Soll',
//c.CostCenter as 'Kostenstelle Haben',
//(select count(*) from invoicebase ib where ib.supportconceptoid = sc.oid),
//crpRateFactor.`CostRateValue`,
//cb2sc.ApprovedStartDate,
//sr.`GeleisteteFLM`,
//'Stundensatz',
//'Betrag'
var srList = DAOFactory.GenericDAO.GetAllActiveAndArchived<SupportConcept>();
Dictionary<long, List<SupportConcept>> customer2SupportConcepts = new Dictionary<long, List<SupportConcept>>();
foreach (var sc in srList)
{
var coid = sc.Customer.Oid.Value;
if (!customer2SupportConcepts.ContainsKey(coid))
{
customer2SupportConcepts.Add(coid, new List<SupportConcept>());
}
customer2SupportConcepts[coid].Add(sc);
}
List<CustomerDataRow> datarows = new List<CustomerDataRow>();
DateTime dtOut;
foreach (DataRow row in dt.Rows)
{
CustomerDataRow cr = new CustomerDataRow();
datarows.Add(cr);
cr.OrgOid = (long)row.ItemArray[0];
cr.OrgName = (String)row.ItemArray[1];
cr.CustomerOid = (long)row.ItemArray[2];
var count = (long) row.ItemArray[5];
cr.Abgerechnet = count > 0;
cr.Bewilligt = DateTime.TryParse(row.ItemArray[7].ToString(), out dtOut);
cr.Minuten = Math.Round((decimal)row.ItemArray[8] / 60, 2, MidpointRounding.AwayFromZero);
if (row.ItemArray[9] != null && row.ItemArray[9] != DBNull.Value)
{
cr.Stundensatz = (decimal) row.ItemArray[9];
}
if (row.ItemArray[10] != null && row.ItemArray[10] != DBNull.Value)
{
cr.Betrag = (decimal)row.ItemArray[10];
}
cr.SupportConceptOid = (long)row.ItemArray[11];
cr.Eingereicht = DateTime.TryParse(row.ItemArray[12].ToString(), out dtOut);
cr.Datum = date;
cr.Erstantrag = IstErstantrag(cr.CustomerOid, cr.SupportConceptOid, customer2SupportConcepts);
cr.IstBezahlt = (long)row.ItemArray[13] > 0;
}
foreach (var dr in datarows)
{
ResultDataRow currentRow = null;
if (dr.Bewilligt)
{
if (dr.Abgerechnet)
{
if (dr.IstBezahlt)
{
currentRow = row1;
}
else
{
currentRow = row2;
}
}
else
{
if (!dr.OrgName.Contains("Jugendamt") && (dr.OrgName == "LVR" || dr.OrgName.Contains("Düsseldorf -Amt") || dr.OrgName == "Landschaftsverband Rheinland"))
{
currentRow = row3;
}
else
{
currentRow = row4;
}
}
}
else
{
if (!dr.Erstantrag)
{
if (dr.Eingereicht)
{
currentRow = row5;
}
else
{
currentRow = row6;
}
}
else
{
if (dr.Eingereicht)
{
currentRow = row7;
}
else
{
currentRow = row8;
}
}
}
currentRow.Betrag += dr.Betrag;
currentRow.FLS += dr.Minuten;
if (currentRow.Stundensatz >= 0)
{
if (currentRow.Stundensatz == 0)
{
currentRow.Stundensatz = dr.Stundensatz;
}
else
{
if (currentRow.Stundensatz != dr.Stundensatz)
{
currentRow.Stundensatz = -9999;
}
}
}
}
List<ResultDataRow> resultList = new List<ResultDataRow>();
resultList.Add(row1);
resultList.Add(row2);
resultList.Add(row3);
resultList.Add(row4);
resultList.Add(row5);
resultList.Add(row6);
resultList.Add(row7);
resultList.Add(row8);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Posten;Typ;Untertyp;Mit Wem;Zum;Anzahl FLS;Satz;Betrag");
foreach (var rd in resultList)
{
sb.AppendLine(SerializeRow(rd));
}
return sb.ToString();
}
private static string SerializeRow(ResultDataRow rd)
{
if (rd.Stundensatz < 0)
{
rd.Stundensatz = 0;
}
return String.Format("{0};{1};{2};{3};{4:dd.MM.yyyy};{5:0.00};{6:0.00};{7:0.00}",
rd.Posten, rd.Typ, rd.Untertyp, rd.Kostentraeger, rd.Datum, rd.FLS, rd.Stundensatz, rd.Betrag);
}
private static bool IstErstantrag(long customerOid, long supportConceptOid, Dictionary<long, List<SupportConcept>> customer2SupportConcepts)
{
if (customer2SupportConcepts.ContainsKey(customerOid))
{
var list = customer2SupportConcepts[customerOid];
if (list.Count == 1)
{
return true;
}
DateTime thisDate = DateTime.Now;
foreach (var sc in list)
{
if (sc.Oid == supportConceptOid && sc.StartDate.HasValue)
{
thisDate = sc.StartDate.Value;
}
}
foreach (var sc in list)
{
if (sc.StartDate.HasValue && sc.StartDate.Value < thisDate)
{
return false;
}
}
}
return true;
}
private static String GetMonatlicheAbrechnungSql(DateTime date)
{
String sql = @"
SELECT
org.Oid,
org.Name,
c.Oid,
c.DebitorNumber as 'Konto Soll',
c.CostCenter as 'Kostenstelle Haben',
(select count(*) from invoicebase ib where ib.supportconceptoid = sc.oid and ib.`AccountingPeriodStart` < ':Monat_End' AND ib.`AccountingPeriodEnd` >= ':Monat_Start'),
crpRateFactor.`CostRateValue`,
cb2sc.ApprovedStartDate,
sr.`GeleisteteFLM`,
(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` > '2019-04-01') order by IF(crp.`EndDate` is null, MAKEDATE(9999,365),crp.`EndDate`) LIMIT 1 ) as 'Stundensatz',
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` > '2019-04-01') 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` > '2019-04-01') order by IF(crp.`EndDate` is null, MAKEDATE(9999,365),crp.`EndDate`) LIMIT 1 ) * ((100 + crpRateFactor.`CostRateValue`)/100), 2)) AS 'Betrag',
sc.Oid,
sc.SupportConceptSendDate,
(select count(*) from invoicebase ib where ib.ispaid = 1 and ib.supportconceptoid = sc.oid and ib.`AccountingPeriodStart` < ':Monat_End' AND ib.`AccountingPeriodEnd` >= ':Monat_Start')
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 GROUP BY sr2.`CostBearer2SupportConceptOid`)
AS sr ON sr.`CostBearer2SupportConceptOid` = cb2sc.`Oid`
WHERE c.`IsActive` <> 0 AND sc.`IsActive` <> 0
and (sr.`GeleisteteFLM` is not null)
ORDER BY p.`LastName`, p.`FirstName`, cb2sc.`ApprovedStartDate`
";
return sql;
}
public static DataTable ExecuteQuery(String sql, DateTime dt)
{
var newsql = sql;
newsql = newsql.Replace(":Abrechnungsmonat", String.Format("{0:dd.MM.yyyy}", dt));
newsql = newsql.Replace(":Belegnr", String.Format("{0:yyMM}", dt));
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));
return DAOFactory.AdoDAO.ExecuteQuery(newsql).Tables[0];
}
}
internal class CustomerDataRow
{
public long OrgOid { get; set; }
public String OrgName { get; set; }
public long CustomerOid { get; set; }
public bool Abgerechnet { get; set; }
public bool Bewilligt { get; set; }
public decimal Minuten { get; set; }
public decimal Stundensatz { get; set; }
public decimal Betrag { get; set; }
public DateTime Datum { get; set; }
public bool Erstantrag { get; set; }
public bool Eingereicht { get; set; }
public long SupportConceptOid { get; set; }
public bool IstBezahlt { get; set; }
}
internal class ResultDataRow
{
public String Posten { get; set; }
public String Typ { get; set; }
public String Untertyp { get; set; }
public String Kostentraeger { get; set; }
public DateTime Datum { get; set; }
public decimal FLS { get; set; }
public decimal Stundensatz { get; set; }
public decimal Betrag { get; set; }
}
}