Files
BeWoPlaner/ReportImp/DiakonischesWerkMuelheimTwg/Export/DatevExporter.cs

177 lines
6.7 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 BeWo.Service.DCEntityMapper;
using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
namespace DiakonischesWerkMuelheimTwg.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("Datev Export {0:yyyyMM}.csv", dt);
query.QueryResult = GetAbrechnungenString(dt);
return query;
}
public static String GetAbrechnungenString(DateTime date)
{
StringBuilder sb = new StringBuilder();
sb.Append("Betrag;S/H;BU;Gegenkonto;Blg 1;Dat;Konto;Kst;Text");
var s = GetMonatlicheRechnungenString(date);
if (!String.IsNullOrWhiteSpace(s))
{
sb.AppendLine();
sb.Append(s);
}
return sb.ToString();
}
public static String GetMonatlicheRechnungenString(DateTime date)
{
var sql = GetMonatlicheRechnungenSql(date);
var dt = ExecuteQuery(sql, date);
StringBuilder sb = new StringBuilder();
foreach (DataRow row in dt.Rows)
{
if (sb.Length > 0)
{
sb.AppendLine();
}
String buchungstext = "";
long? c2sOid = (long?)row[5];
if (c2sOid.HasValue)
{
var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(c2sOid.Value);
var c = c2s.SupportConcept.Customer;
buchungstext = String.Format("{0}, {1} {2:MM}/{2:yy}", c.Person.LastName, c.Person.FirstName, row[8]);
}
string konto = String.Format("{0}", row[1]).Trim(); // customer.DebitorNumber
string kostenstelle = String.Format("{0}", row[4]).Trim(); // customer.CostCenter
string belegfeld1 = String.Format("{0}", row[3]).Trim(); // ib.invoicenumber
string gegenkonto = ErmittleErloeskonto((long)row[10]); // ib.Oid -> 40920 Pflege/Barbetrag, sonst 40910 ABW
sb.Append(BuildBuchungszeile(row[0], konto, gegenkonto, belegfeld1, row[2], kostenstelle, buchungstext));
}
return sb.ToString();
}
// Spalten: Betrag;S/H;BU;Gegenkonto;Blg 1;Dat;Konto;Kst;Text
private static String BuildBuchungszeile(object betrag, string konto, string gegenkonto, string belegfeld1, object belegdatum, string kostenstelle, string buchungstext)
{
StringBuilder sb = new StringBuilder();
sb.Append(String.Format("{0:0.00}", betrag)); // Betrag
sb.Append(";S"); // S/H
sb.Append(";"); // BU (leer)
sb.Append(";");
sb.Append(gegenkonto); // Gegenkonto
sb.Append(";");
sb.Append(belegfeld1); // Blg 1
sb.Append(";");
sb.Append(String.Format("{0:ddMM}", belegdatum)); // Dat
sb.Append(";");
sb.Append(konto); // Konto
sb.Append(";");
sb.Append(kostenstelle); // Kst (leer)
sb.Append(";");
sb.Append(buchungstext); // Text
return sb.ToString();
}
// Kunde hat kein festes Erloeskonto: 40920 fuer Pflege/Barbetrag, 40910 fuer ABW.
// Massgeblich ist die UnitDescription der InvoiceItems; ist diese leer (Rechnung vor Juli 2026), gilt die ItemDescription.
private static String ErmittleErloeskonto(long invoiceBaseOid)
{
var invoice = DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoiceBaseOid);
if (invoice != null && invoice.ServiceInvoicePeriodList != null)
{
foreach (var period in invoice.ServiceInvoicePeriodList)
{
if (period.InvoiceItemList == null)
{
continue;
}
foreach (var item in period.InvoiceItemList)
{
string text = !String.IsNullOrWhiteSpace(item.UnitDescription) ? item.UnitDescription : item.ItemDescription;
if (EnthaeltPflege(text))
{
return "40920"; // Pflege
}
}
}
}
return "40910"; // ABW (Umkehrschluss: kein Pflege/Barbetrag)
}
private static bool EnthaeltPflege(string text)
{
if (String.IsNullOrEmpty(text))
{
return false;
}
return text.IndexOf("Pflege", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static String GetMonatlicheRechnungenSql(DateTime date)
{
String sql = @"
select
sip.Claim,
c.DebitorNumber,
ib.InvoiceDate,
ib.invoicenumber,
c.CostCenter,
c2s.Oid,
ib.InvoiceId,
c2s.Notice AS 'Kostenstelle',
ib.`AccountingPeriodEnd`,
ib.`AccountingPeriodStart`,
ib.Oid
from
person p
inner join customer c on c.personoid = p.oid
inner join supportconcept sc on sc.customeroid = c.oid
inner join costbearer2supportconcept c2s on c2s.supportconceptoid = sc.oid
inner join invoicebase ib on ib.costbearer2supportconceptoid = c2s.oid
inner join serviceinvoice si on si.invoicebaseoid = ib.oid
inner join serviceinvoiceperiod sip on sip.serviceinvoiceoid = si.oid
WHERE ib.`AccountingPeriodEnd` >= ':Monat_Start' AND ib.`AccountingPeriodEnd` < ':Monat_End' and ib.IsActive = 1 AND (ib.InvoiceId <> 'Bar' OR ib.InvoiceId IS NULL) AND ib.IsExported = 0
order by ib.invoicenumber
";
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_MM", String.Format("{0:MM}", 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];
}
}
}