Hallo zusammen,
ich Biete eine Klassenbibliothek in C# geschrieben da die OpenApi.json (in meinem Fall noch v1.0.0) von SevDesk leider fehlerhaft oder unvollständig waren.
https://github.com/utbert/SevClient
und da ich es in einem anderen Thema angekündigt hatte, auch den Code um Sepa Lastschrift Dateien erstellen zu können
https://github.com/utbert/SepaDirectDebitXML
Das erstellen der XmlDatei läuft bei mir wie folgt ab:
public async Task CreateSepaDirectDebitXml()
{
await Task.Run(() =>
{
List<SevDeskClient.Invoice> invoices = SevDeskClient.Invoice.GetList(
embed: new string[] { "tags", "paymentMethod", "contact", "contact.tags" },
filter: new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("paymentMethod[id]", "21920"),
new KeyValuePair<string, string>("paymentMethod[objectName]", "PaymentMethod"),
new KeyValuePair<string, string>("status", "200"),
new KeyValuePair<string, string>("startDate", DateTime.Now.AddDays(-14).ToShortDateString()),
}.ToArray());
// ToDo: Nur starten wenn Summe größer x ???
if (invoices.Count > 0)
{
// ToDo: Firmendaten runter laden
SEPA.Pain_008.Document document = new SEPA.Pain_008.Document("name", "iban", "Bic", "gident", SEPA.Pain_008.PaymentTypeInformation.SequenceTypeEnum.RCUR);
// Lastschrift-erstellt Tag von SevDeskLaden oder erstellen
SevDeskClient.Tag LsErstelltTag = SevDeskClient.Tag.GetList(filter: new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("name", "Lastschrift-erstellt") }).First();
if (LsErstelltTag == null) new SevDeskClient.Tag() { name = "Lastschrift-erstellt" }.Add(out LsErstelltTag);
foreach (SevDeskClient.Invoice invoice in invoices)
{
string mrTag = invoice.contact.Tags.SingleOrDefault(s => s.name.StartsWith("MR"))?.name;//?? $"MR#{invoice.contact.CustomerNumber}#{DateTime.Now:dd.MM.yyyy}";
string mRef = mrTag?.Split('#')[1] ?? "";
string mDate = mrTag?.Split('#')[2] ?? "";
string debtorName = invoice.contact.GetNameString(false);
// abweichender Kontoinhaber
SevDeskClient.Tag akiTag = invoice.contact.Tags.SingleOrDefault(s => s.name.StartsWith("AKI"));
if (akiTag != null) debtorName = (akiTag.name.Split('#'))[1];
// Iban validieren
SinKien.IBAN4Net.IbanFormatViolation ibanFormatViolation = SinKien.IBAN4Net.IbanFormatViolation.NO_VIOLATION;
bool IbanValid = SinKien.IBAN4Net.IbanUtils.IsValid(invoice.contact.BankAccount, out ibanFormatViolation);
SinKien.IBAN4Net.BicFormatViolation bicFormatViolation = SinKien.IBAN4Net.BicFormatViolation.NO_VIOLATION;
bool BicValid = SinKien.IBAN4Net.BicUtils.IsValid(invoice.contact.BankNumber, out bicFormatViolation);
if (IbanValid && BicValid && !string.IsNullOrEmpty(mRef) && DateTime.TryParse(mDate, out DateTime dt))
{
document.AddTransaction(new SEPA.Pain_008.DirectDebitTransferTransactionInformation(
debtorName,
invoice.contact.BankAccount,
invoice.contact.BankNumber,
(mrTag.Split('#'))[1],
Double.Parse(invoice.sumGross.Replace(".", ",")),
dt,
$"Firmenname {invoice.invoiceNumber} vom {invoice.invoiceDate.Value.Date.ToShortDateString()}"));
#if !DEBUG
SevDeskClient.TagRelation.Add(LsErstelltTag, invoice, out SevDeskClient.TagRelation tagRelation);
#endif
}
// Email Kontonummer ungültig
else
{
using (MailMessage message = new MailMessage("irgend@jemand.de", "irgend@jemand.de", $"ungültige Lastschriftdaten - {invoice.contact.GetNameString()}",
$"IBAN {invoice.contact.BankAccount} - " + (IbanValid ? "gültig" : "ungültig") +
$"\nBic { invoice.contact.BankNumber} - " + (BicValid ? "gültig" : "ungültig") +
$"\nMandatsreferenz { mRef } - " + (!string.IsNullOrEmpty(mRef) ? "gültig" : "ungültig") +
$"\nDatum Mandat { mDate } - " + (DateTime.TryParse(mDate, out DateTime dt2) ? "gültig" : "ungültig")
))
{
message.From = new MailAddress("irgend@jemand.de", "Subject");
using (SmtpClient smtpClient = new SmtpClient("smtp.strato.de", 587))
{
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("user", "pw");
smtpClient.EnableSsl = true;
smtpClient.Send(message);
}
}
}
}
if (document.cstmrDrctDbtInitn.PaymentInformation.DirectDebitTransferTransactionInformation.Any())
{
using (MailMessage message = new MailMessage("irgend@jemand.de", "irgend@jemand.de", "SEPA DirectDebit XML-File", ""))
{
message.From = new MailAddress("irgend@jemand.de", "Subject");
message.Attachments.Add(new Attachment(document.CreateXmlStream(), $"SEPA_{DateTime.Now:ddMMyyyy}.xml"));
using (SmtpClient smtpClient = new SmtpClient("smtp.strato.de", 587))
{
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("user", "pw");
smtpClient.EnableSsl = true;
smtpClient.Send(message);
}
}
}
}
});
}
Extensionmethode GetNameString
public static string GetNameString(this SevDeskClient.Contact contact, bool mitAnrede = true)
{
string anrede = contact.Gender == "w" ? "Frau" : contact.Gender == "m" ? "Herr" : contact.Gender ?? "";
anrede = mitAnrede ? anrede : "";
string name = String.Join(" ", new string[] { anrede, contact.Titel, contact.Name, contact.Surename, contact.Familyname }.Where(w => !string.IsNullOrWhiteSpace(w)));
return name;
}
Grundlage für den SepaXmlCode war folgendes Dokument.
https://www.hypovereinsbank.de/content/dam/hypovereinsbank/unternehmen/pdf/Downloadcenter/SEPA-Formate-de.pdf
Ich habe das alles nur soweit Entwickelt wie ich es für meine Zwecke gebraucht habe, aber der Vollständigkeit halber Fehlen leider noch verschiedene Dinge.
Ich würde mich freuen wenn es Hobbyentwickler gäbe, die an dem Projekt SevClient auf Git mitwirken wollen würden …