Fakturierung per EDIFACT: Rechnungen, Gutschriften, Streitfälle und Kontoauszüge. EdiInvoicWrite berechnet Netto-, Steuer- und Bruttosummen aus den Positionen selbst — Summenwerte im Header werden ignoriert und überschrieben.
INVOIC (BGM 380=Rechnung, 381=Gutschrift, 383=Belastung, 386=Vorauszahlungsanforderung)
INVCON (BGM 44) — Dauerrechnung / Rahmenvertrag
COMDIS (BGM 34) — Handelsstreit mit Freitext-Begründung
COACSU (BGM 36) — Kontoauszug (Netto- und Bruttosaldo)
Steuertypen:
| Konstante | Code | Satz |
EDI_INVOIC_TAX_S | S | 19 % Standard |
EDI_INVOIC_TAX_AA | AA | 7 % Ermäßigt |
EDI_INVOIC_TAX_Z | Z | 0 % Nullsatz |
EDI_INVOIC_TAX_E | E | 0 % Steuerfrei |
import std.edi.invoice;
import std.alloc;
import std.string;
fn Feld(p: int64, l: int64): pchar {
var b: int64 := alloc(l + 1);
var i: int64 := 0;
while (i < l) { poke8(b + i, peek8(p + i)); i := i + 1; }
poke8(b + l, 0);
return b as pchar;
}
// Betrag in Cent als "123.45" ausgeben
fn Geld(cent: int64): pchar {
var r: int64 := cent - (cent / 100) * 100;
var nk: pchar := IntToStr(r);
if (r < 10) { nk := StrConcat("0", nk); }
return StrConcat(StrConcat(IntToStr(cent / 100), ","), nk);
}
fn main(): int64 {
var hdr: int64 := alloc(EDI_INVOIC_HDR_SIZE);
var i: int64 := 0;
while (i < EDI_INVOIC_HDR_SIZE) { poke8(hdr + i, 0); i := i + 1; }
poke64(hdr + EDI_INVOIC_HDR_NUM, "RE-2026-4711"c as int64);
poke64(hdr + EDI_INVOIC_HDR_NUMLEN, 12);
poke64(hdr + EDI_INVOIC_HDR_DATE, "20260813"c as int64);
poke64(hdr + EDI_INVOIC_HDR_DATELEN, 8);
poke64(hdr + EDI_INVOIC_HDR_BGMQUAL, 380); // 380 = Rechnung
poke64(hdr + EDI_INVOIC_HDR_SUPPLIER, "4098765000004"c as int64);
poke64(hdr + EDI_INVOIC_HDR_SUPLEN, 13);
poke64(hdr + EDI_INVOIC_HDR_BUYER, "4012345000009"c as int64);
poke64(hdr + EDI_INVOIC_HDR_BUYLEN, 13);
poke64(hdr + EDI_INVOIC_HDR_CURRENCY, "EUR"c as int64);
poke64(hdr + EDI_INVOIC_HDR_CURLEN, 3);
var lines: int64 := alloc(2 * EDI_INVOIC_LINE_SIZE);
i := 0;
while (i < 2 * EDI_INVOIC_LINE_SIZE) { poke8(lines + i, 0); i := i + 1; }
poke64(lines + EDI_INVOIC_LINE_GTIN, "04012345678901"c as int64);
poke64(lines + EDI_INVOIC_LINE_GTINLEN, 14);
poke64(lines + EDI_INVOIC_LINE_QTY, 24);
poke64(lines + EDI_INVOIC_LINE_PRICE, 1999);
poke64(lines + EDI_INVOIC_LINE_NETAMT, 24 * 1999);
poke64(lines + EDI_INVOIC_LINE_TAXTYPE, EDI_INVOIC_TAX_S);
poke64(lines + EDI_INVOIC_LINE_LINENO, 1);
var l1: int64 := lines + EDI_INVOIC_LINE_SIZE;
poke64(l1 + EDI_INVOIC_LINE_GTIN, "04012345678918"c as int64);
poke64(l1 + EDI_INVOIC_LINE_GTINLEN, 14);
poke64(l1 + EDI_INVOIC_LINE_QTY, 6);
poke64(l1 + EDI_INVOIC_LINE_PRICE, 4950);
poke64(l1 + EDI_INVOIC_LINE_NETAMT, 6 * 4950);
poke64(l1 + EDI_INVOIC_LINE_TAXTYPE, EDI_INVOIC_TAX_AA);
poke64(l1 + EDI_INVOIC_LINE_LINENO, 2);
var out: int64 := alloc(4096);
var n: int64 := EdiInvoicWrite(hdr, lines, 2, out, 4096);
PrintLn(Feld(out, n));
var hdr2: int64 := alloc(EDI_INVOIC_HDR_SIZE);
var lin2: int64 := alloc(8 * EDI_INVOIC_LINE_SIZE);
var cnt: int64 := EdiInvoicRead(out, n, hdr2, lin2, 8);
PrintLn(StrConcat("Positionen: ", IntToStr(cnt)));
PrintLn(StrConcat("Netto: ", Geld(peek64(hdr2 + EDI_INVOIC_HDR_NETTOTAL))));
PrintLn(StrConcat("Steuer: ", Geld(peek64(hdr2 + EDI_INVOIC_HDR_TAXTOTAL))));
PrintLn(StrConcat("Brutto: ", Geld(peek64(hdr2 + EDI_INVOIC_HDR_GROSSTOTAL))));
PrintLn(StrConcat("Validierung: ", IntToStr(EdiInvoicValidate(hdr2, lin2, cnt))));
return 0;
}
BGM+380+RE-2026-4711+9'DTM+137:20260813:102'NAD+SU+4098765000004::9'NAD+BY+4012345000009::9'CUX+2:EUR:4'LIN+1++04012345678901:SRV'QTY+47:24'PRI+AAA:19.99:CP'MOA+203:479.76'TAX+7+VAT+++:::S'LIN+2++04012345678918:SRV'QTY+47:6'PRI+AAA:49.50:CP'MOA+203:297.00'TAX+7+VAT+++:::AA'UNS+S'TAX+7+VAT+++:::S'MOA+125:479.76'MOA+124:91.15'TAX+7+VAT+++:::AA'MOA+125:297.00'MOA+124:20.79'MOA+77:776.76'MOA+176:111.94'MOA+9:888.70'CNT+2:2'
Positionen: 2
Netto: 776,76
Steuer: 111,94
Brutto: 888,70
Validierung: 0
Die Steuer wird je Steuersatz getrennt ausgewiesen (MOA+125 Nettoteilbetrag, MOA+124 Steuerbetrag), erst danach folgen die Gesamtsummen MOA+77 (netto), MOA+176 (Steuer) und MOA+9 (brutto).
import std.edi.invoice;
import std.alloc;
import std.string;
fn main(): int64 {
var msg: pchar := "BGM+380+RE-2026-4711+9'DTM+137:20260813:102'NAD+SU+4098765000004::9'NAD+BY+4012345000009::9'CUX+2:EUR:4'LIN+1++04012345678901:SRV'QTY+47:24'PRI+AAA:19.99:CP'MOA+203:479.76'TAX+7+VAT+++:::S'UNS+S'MOA+77:479.76'MOA+176:91.15'MOA+9:570.91'CNT+1:1'"c;
var hdr: int64 := alloc(EDI_INVOIC_HDR_SIZE);
var lines: int64 := alloc(64 * EDI_INVOIC_LINE_SIZE);
var count: int64 := EdiInvoicRead(msg as int64, StrLen(msg), hdr, lines, 64);
var rc: int64 := EdiInvoicValidate(hdr, lines, count);
if (rc == 0) {
PrintLn(StrConcat("Rechnung rechnerisch korrekt, Positionen: ", IntToStr(count)));
PrintLn(StrConcat("Brutto in Cent: ", IntToStr(peek64(hdr + EDI_INVOIC_HDR_GROSSTOTAL))));
} else {
if (rc == 1) { PrintLn("Nettosumme stimmt nicht"); }
if (rc == 3) { PrintLn("Bruttosumme stimmt nicht"); }
}
free(lines, 64 * EDI_INVOIC_LINE_SIZE);
free(hdr, EDI_INVOIC_HDR_SIZE);
return 0;
}
Rechnung rechnerisch korrekt, Positionen: 1
Brutto in Cent: 57091
EdiInvoicValidate liefert 0 bei Übereinstimmung, 1 bei falscher Nettosumme und 3 bei falscher Bruttosumme; Toleranz ist jeweils 1 Cent.
| Unit | Datei |
std.edi.invoice | std/edi/invoice.lyx |
Letzte Aktualisierung: 2026-08-13 — beide Beispiele lauffähig gemacht und ausgeführt (lyxc 1.0.17K), echte EDIFACT-Ausgabe samt Steueraufteilung je Satz ergänzt, Rückgabewerte von EdiInvoicValidate (0/1/3) und die Rolle von NETAMT klargestellt
Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).