1

E-Rechnung / Selfmade Lösung für Mac App

Ich habe mal versucht, eine XRechnung per Button zu erstellen. Es ist definitiv noch work in progress und ich hab noch einige offene Fragen. Aber das Grundgerüst steht und scheint zu funktionieren (habe einige Tests auf https://erechnungsvalidator.service-bw.de/ gemacht, die validiert wurden).

Aber nochmal, ganz deutlich als Disclaimer vorab: das ist eher so quick and dirty (siehe z.B. BT-106 = BT-109 .... uiuiui). Ich habe keine Ahnung, ob man das so überhaupt machen darf. Und es ist eher eine Grundstruktur für den Austausch hier.

Ich habe versucht möglichst die Variablen so zu definieren, damit sie jeder nach seinem Bedarf anpassen kann. Ich denke, wenn man sich mit der Ninox Sprache etwas auskennt, sollte man damit zurecht kommen (ich selbst bin kein Programmier, nur Ninox Anwender seit ein paar Jahren.

Via Button wird ein XML File im Bildfeld "E-Rechnung" erstellt.

Was meint die Schwarmintelligenz hier? Kann man das so machen? Oder ist das alles viel zu "provisorisch" gedacht?

Hier kommt mein Code:

 

let my := this;

let empfaenger_mail := (select Ansprechpartner)[Kunde = my.Kunde and Rechnungsversand = true].Mail;

let datumsformat := "YYYY-MM-DD";

let var_rechnungsdatum := format(Rechnungsdatum, datumsformat);

let var_zahlungsziel := format(Rechnungsdatum + Zahlungsziel, datumsformat);

let var_buyerreference := Kunde.'BuyerReference (E-Rechnung)';

let var_name := "Vorname Nachname";

let var_str := "Musterstr. 3";

let var_plz := "12345";

let var_ort := "Ort";

let var_ustid := "umsatzsteuer-id";

let var_steuernummer := "steuernummer";

let var_telefon := "telefon";

let var_mail := "mail";

let var_iban := "iban";

let var_bic := "bic";

let eur_format := "#,##0 #.#";

let bt106 := format(number(sum(Posten.Netto)), eur_format);

let bt109 := bt106;

let bt110 := format(sum(Posten.'USt. Betrag'), eur_format);

let bt112 := format(sum(Posten.Brutto), eur_format);

let bt115 := bt112;

let erechnung := "<?xml version=""1.0"" encoding=""UTF-8""?>

<Invoice xmlns=""urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"" xmlns:cac=""urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"" xmlns:cec=""urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"" xmlns:cbc=""urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"">

<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>

<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>

<cbc:ID>" +

Rechnungsnummer +

"</cbc:ID>

<cbc:IssueDate>" +

var_rechnungsdatum +

"</cbc:IssueDate>

<cbc:DueDate>" +

var_zahlungsziel +

"</cbc:DueDate>

 

<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>

<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>

<cbc:BuyerReference>" +

var_buyerreference +

"</cbc:BuyerReference>

<cac:AccountingSupplierParty>

<cac:Party>

<cbc:EndpointID schemeID=""EM"">info@dominic-kolb.de</cbc:EndpointID>

<cac:PartyName>

<cbc:Name>" +

var_name +

"</cbc:Name>

</cac:PartyName>

<cac:PostalAddress>

<cbc:StreetName>" +

var_str +

"</cbc:StreetName>

<cbc:CityName>" +

var_ort +

"</cbc:CityName>

<cbc:PostalZone>" +

var_plz +

"</cbc:PostalZone>

<cac:Country>

<cbc:IdentificationCode>DE</cbc:IdentificationCode>

</cac:Country>

</cac:PostalAddress>

<cac:PartyTaxScheme>

<cbc:CompanyID>" +

var_ustid +

"</cbc:CompanyID>

<cac:TaxScheme>

<cbc:ID>VAT</cbc:ID>

</cac:TaxScheme>

</cac:PartyTaxScheme>

<cac:PartyTaxScheme>

<cbc:CompanyID>" +

var_steuernummer +

"</cbc:CompanyID>

<cac:TaxScheme>

<cbc:ID>FC</cbc:ID>

</cac:TaxScheme>

</cac:PartyTaxScheme>

<cac:PartyLegalEntity>

<cbc:RegistrationName>" +

var_name +

"</cbc:RegistrationName>

</cac:PartyLegalEntity>

<cac:Contact>

<cbc:Name>" +

var_name +

"</cbc:Name>

<cbc:Telephone>" +

var_telefon +

"</cbc:Telephone>

<cbc:ElectronicMail>" +

var_mail +

"</cbc:ElectronicMail>

</cac:Contact>

</cac:Party>

</cac:AccountingSupplierParty>

<cac:AccountingCustomerParty>

<cac:Party>

<cbc:EndpointID schemeID=""EM"">" +

empfaenger_mail +

"</cbc:EndpointID>

<cac:PartyName>

<cbc:Name>" +

if cnt(first(Posten.Rechnungsadresse)) > 0 then

first(Posten.Rechnungsadresse.Firmenname)

else

Kunde.Firmenname

end +

"</cbc:Name>

</cac:PartyName>

<cac:PostalAddress>

<cbc:StreetName>" +

if cnt(first(Posten.Rechnungsadresse)) > 0 then

first(Posten.Rechnungsadresse.'Straße')

else

Kunde.'Straße'

end +

"</cbc:StreetName>

<cbc:CityName>" +

if cnt(first(Posten.Rechnungsadresse)) > 0 then

first(Posten.Rechnungsadresse.Ort)

else

Kunde.Ort

end +

"</cbc:CityName>

<cbc:PostalZone>" +

if cnt(first(Posten.Rechnungsadresse)) > 0 then

first(Posten.Rechnungsadresse.PLZ)

else

Kunde.PLZ

end +

"</cbc:PostalZone>

<cac:Country>

<cbc:IdentificationCode>DE</cbc:IdentificationCode>

</cac:Country>

</cac:PostalAddress>

<cac:PartyLegalEntity>

<cbc:RegistrationName>" +

if cnt(first(Posten.Rechnungsadresse)) > 0 then

first(Posten.Rechnungsadresse.Firmenname)

else

Kunde.Firmenname

end +

"</cbc:RegistrationName>

</cac:PartyLegalEntity>

</cac:Party>

</cac:AccountingCustomerParty>

<cac:Delivery>

<cbc:ActualDeliveryDate>" +

var_rechnungsdatum +

"</cbc:ActualDeliveryDate>

</cac:Delivery>

<cac:PaymentMeans>

<cbc:PaymentMeansCode>58</cbc:PaymentMeansCode>

<cbc:PaymentID>" +

"Rechnung Nr " +

Rechnungsnummer +

"</cbc:PaymentID>

<cac:PayeeFinancialAccount>

<cbc:ID>" +

var_iban +

"</cbc:ID>

<cbc:Name>" +

var_name +

"</cbc:Name>

<cac:FinancialInstitutionBranch>

<cbc:ID>" +

var_bic +

"</cbc:ID>

</cac:FinancialInstitutionBranch>

</cac:PayeeFinancialAccount>

</cac:PaymentMeans>

<cac:TaxTotal>

<cbc:TaxAmount currencyID=""EUR"">" +

bt110 +

"</cbc:TaxAmount>

<cac:TaxSubtotal>

<cbc:TaxableAmount currencyID=""EUR"">" +

bt106 +

"</cbc:TaxableAmount>

<cbc:TaxAmount currencyID=""EUR"">" +

bt110 +

"</cbc:TaxAmount>

<cac:TaxCategory>

<cbc:ID>S</cbc:ID>

<cbc:Percent>19</cbc:Percent>

<cac:TaxScheme>

<cbc:ID>VAT</cbc:ID>

</cac:TaxScheme>

</cac:TaxCategory>

</cac:TaxSubtotal>

</cac:TaxTotal>

<cac:LegalMonetaryTotal>

<cbc:LineExtensionAmount currencyID=""EUR"">" +

bt106 +

"</cbc:LineExtensionAmount>

<cbc:TaxExclusiveAmount currencyID=""EUR"">" +

bt109 +

"</cbc:TaxExclusiveAmount>

<cbc:TaxInclusiveAmount currencyID=""EUR"">" +

bt112 +

"</cbc:TaxInclusiveAmount>

<cbc:PrepaidAmount currencyID=""EUR"">0</cbc:PrepaidAmount>

<cbc:PayableAmount currencyID=""EUR"">" +

bt115 +

"</cbc:PayableAmount>

</cac:LegalMonetaryTotal>" +

for i in Posten do

"<cac:InvoiceLine>

<cbc:ID>" +

i +

"</cbc:ID>

<cbc:InvoicedQuantity unitCode=""C62"">1</cbc:InvoicedQuantity>

<cbc:LineExtensionAmount currencyID=""EUR"">" +

i.format(Netto, eur_format) +

"</cbc:LineExtensionAmount>

<cac:Item>

<cbc:Name>" +

i.Beschreibung +

"</cbc:Name>

<cac:ClassifiedTaxCategory>

<cbc:ID>S</cbc:ID>

<cbc:Percent>" +

i.number(Steuersatz) +

"</cbc:Percent>

<cac:TaxScheme>

<cbc:ID>VAT</cbc:ID>

</cac:TaxScheme>

</cac:ClassifiedTaxCategory>

</cac:Item>

<cac:Price>

<cbc:PriceAmount currencyID=""EUR"">" +

i.format(Netto, eur_format) +

"</cbc:PriceAmount>

<cbc:BaseQuantity unitCode=""C62"">1</cbc:BaseQuantity>

</cac:Price>

</cac:InvoiceLine>"

end +

"

</Invoice>";

let myFilename := Rechnungsnummer + "_" + first(Posten.Kunde.Kurzname) + ".xml";

let File := createTextFile(this, raw(erechnung), myFilename);

'E-Rechnung' := File

3 Antworten

null
    • Icarus_Ralf_Becker
    • vor 2 Monaten
    • Gemeldet - anzeigen

    Ich habe es in meinen Kundendatenbanken fast genauso gemacht. Ich habe die Struktur von XRechnung 3.0.1 zentral abgelegt, Platzhalter eingesetzt, und ersetze beim Erzeugen die Platzhalter nur noch mit den Nutzdaten. Funktioniert top und ohne Fehler.

      • Sprecher
      • info.23
      • vor 2 Monaten
      • Gemeldet - anzeigen

       

      Interessant zu hören - nutzt du es schon im Alltag? Wenn ja - schickst du das einfach so an den Kunden raus oder hast du noch irgendwie eine "Validierungs-Schritt" eingebaut, um sicherzugehen, dass alles passt?

      • Icarus_Ralf_Becker
      • vor 2 Monaten
      • Gemeldet - anzeigen

       Ja, aber erst seit wenigen Tagen. Zur Überprüfung nutze ich 2 Dinge: (1) vor dem Erzeugen der XML-Datei wird geprüft, ob im Rechnungsdatensatz und im verknüpften Kundendatensatz alle erforderlichen Angaben vorhanden sind. Wenn nicht, wird die XML nicht erzeugt, kann aber nachträglich erzeugt werden. (2) Per API-Call lasse ich die USt-ID´s überprüfen.