410 lines
16 KiB
C#
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; }
|
|
}
|
|
} |