std.edi.orders
Bestellprozess per EDIFACT: Bestellung, Auftragsbestätigung und Änderungsauftrag. Alle vier NAD-Rollen (Käufer, Lieferant, Lieferadresse, Rechnungsempfänger) werden beim Lesen automatisch extrahiert.
- ORDERS (BGM 220) — Bestellung (Purchase Order)
- ORDRSP (BGM 231) — Auftragsbestätigung mit positionsgenauen Status-Codes
- ORDCHG (BGM 230) — Änderungsauftrag mit laufender Änderungsnummer
import std.edi.orders;
import std.alloc;
import std.string;
// Zero-Copy-Felder sind nicht nullterminiert - terminierte Kopie fuer die Ausgabe.
fn Feld(ptr: int64, len: int64): pchar {
var b: int64 := alloc(len + 1);
var i: int64 := 0;
while (i < len) { poke8(b + i, peek8(ptr + i)); i := i + 1; }
poke8(b + len, 0);
return b as pchar;
}
fn main(): int64 {
// Kopf - Structs immer selbst nullen
var hdr: int64 := alloc(EDI_ORDER_HDR_SIZE);
var i: int64 := 0;
while (i < EDI_ORDER_HDR_SIZE) { poke8(hdr + i, 0); i := i + 1; }
poke64(hdr + EDI_ORDER_HDR_NUM, "BST-2026-0815"c as int64);
poke64(hdr + EDI_ORDER_HDR_NUMLEN, 13);
poke64(hdr + EDI_ORDER_HDR_DATE, "20260813"c as int64);
poke64(hdr + EDI_ORDER_HDR_DATELEN, 8);
poke64(hdr + EDI_ORDER_HDR_BUYER_GLN, "4012345000009"c as int64);
poke64(hdr + EDI_ORDER_HDR_BUYER_GLNL, 13);
poke64(hdr + EDI_ORDER_HDR_SUP_GLN, "4098765000004"c as int64);
poke64(hdr + EDI_ORDER_HDR_SUP_GLNL, 13);
// Zwei Positionen
var lines: int64 := alloc(2 * EDI_ORDER_LINE_SIZE);
i := 0;
while (i < 2 * EDI_ORDER_LINE_SIZE) { poke8(lines + i, 0); i := i + 1; }
var l0: int64 := lines;
poke64(l0 + EDI_ORDER_LINE_GTIN, "04012345678901"c as int64);
poke64(l0 + EDI_ORDER_LINE_GTINLEN, 14);
poke64(l0 + EDI_ORDER_LINE_QTY, 24);
poke64(l0 + EDI_ORDER_LINE_PRICE, 1999); // 19,99 EUR
poke64(l0 + EDI_ORDER_LINE_LINENO, 1);
var l1: int64 := lines + EDI_ORDER_LINE_SIZE;
poke64(l1 + EDI_ORDER_LINE_GTIN, "04012345678918"c as int64);
poke64(l1 + EDI_ORDER_LINE_GTINLEN, 14);
poke64(l1 + EDI_ORDER_LINE_QTY, 6);
poke64(l1 + EDI_ORDER_LINE_PRICE, 4950); // 49,50 EUR
poke64(l1 + EDI_ORDER_LINE_LINENO, 2);
if (EdiOrdersValidate(hdr, lines, 2) != EDI_OK) { PrintLn("ungueltig"); return 1; }
var out: int64 := alloc(4096);
var n: int64 := EdiOrdersWrite(hdr, lines, 2, out, 4096);
PrintLn(Feld(out, n));
// Und wieder zurueck
var hdr2: int64 := alloc(EDI_ORDER_HDR_SIZE);
var lin2: int64 := alloc(8 * EDI_ORDER_LINE_SIZE);
var cnt: int64 := EdiOrdersRead(out, n, hdr2, lin2, 8);
PrintLn(StrConcat("Positionen: ", IntToStr(cnt)));
PrintLn(StrConcat("Bestellnr: ", Feld(peek64(hdr2 + EDI_ORDER_HDR_NUM), peek64(hdr2 + EDI_ORDER_HDR_NUMLEN))));
PrintLn(StrConcat("Summe/100: ", IntToStr(peek64(hdr2 + EDI_ORDER_HDR_TOTAL))));
return 0;
}
BGM+220+BST-2026-0815+9'DTM+137:20260813:102'NAD+BY+4012345000009::9'NAD+SU+4098765000004::9'LIN+1++04012345678901:SRV'QTY+21:24'PRI+AAA:19.99:CP'LIN+2++04012345678918:SRV'QTY+21:6'PRI+AAA:49.50:CP'UNS+S'MOA+77:776.76'CNT+2:2'
Positionen: 2
Bestellnr: BST-2026-0815
Summe/100: 77676
EdiOrdersWrite erzeugt nur den Nachrichtenrumpf. Umschlag (UNA/UNB/UNH … UNT/UNZ) kommt aus std.edi.core. Den Gesamtbetrag (MOA+77) rechnet die Funktion selbst aus den Positionen aus — ihn im Kopf zu setzen ist nur für EdiOrdersValidate nötig.
Imports
std.edi.corestd.alloc
Structs
EdiOrderLine (EDI_ORDER_LINE_SIZE = 80 Bytes)
| Offset-Konstante | Inhalt |
|---|---|
EDI_ORDER_LINE_GTIN / EDI_ORDER_LINE_GTINLEN | GTIN-Zeiger und -Länge |
EDI_ORDER_LINE_QTY | Bestellmenge |
EDI_ORDER_LINE_UNIT / EDI_ORDER_LINE_UNITLEN | Mengeneinheit (optional) |
EDI_ORDER_LINE_PRICE | Einzelpreis × 100 (Festkomma) |
EDI_ORDER_LINE_TAXRATE | Steuersatz × 100 (z. B. 1900 = 19,00 %) |
EDI_ORDER_LINE_DATE | Zeiger auf Lieferdatum „YYYYMMDD“ (0 = kein Wunschtermin) |
EDI_ORDER_LINE_STATUS | Position-Status: 0=normal, 1=bestätigt, 5=geändert, 7=abgelehnt |
EDI_ORDER_LINE_LINENO | Zeilennummer (1-basiert) |
EdiOrderHdr (EDI_ORDER_HDR_SIZE = 112 Bytes)
| Offset-Konstante | Inhalt |
|---|---|
EDI_ORDER_HDR_NUM / EDI_ORDER_HDR_NUMLEN | Bestellnummer |
EDI_ORDER_HDR_DATE / EDI_ORDER_HDR_DATELEN | Bestelldatum |
EDI_ORDER_HDR_BUYER_GLN / EDI_ORDER_HDR_BUYER_GLNL | GLN Käufer (NAD+BY) |
EDI_ORDER_HDR_SUP_GLN / EDI_ORDER_HDR_SUP_GLNL | GLN Lieferant (NAD+SU) |
EDI_ORDER_HDR_DELIV_GLN / EDI_ORDER_HDR_DELIV_GLNL | GLN Lieferadresse (NAD+DP) |
EDI_ORDER_HDR_INV_GLN / EDI_ORDER_HDR_INV_GLNL | GLN Rechnungsempfänger (NAD+IV) |
EDI_ORDER_HDR_TOTAL | Gesamtbetrag × 100 (MOA+77) |
EDI_ORDER_HDR_CHANGENO | Änderungsnummer (ORDCHG: muss pro Änderung erhöht werden) |
Funktionen
ORDERS
| Signatur | Beschreibung |
|---|---|
EdiOrdersWrite(hdr: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 | Schreibt ORDERS. Gibt -1 wenn Bestellnummer fehlt. |
EdiOrdersRead(buf: int64, bufLen: int64, hdr: int64, lines: int64, maxLines: int64): int64 | Parst ORDERS; befüllt hdr und lines. Gibt Zeilenanzahl zurück. Alle 4 NAD-Rollen werden extrahiert. |
EdiOrdersValidate(hdr: int64, lines: int64, lineCount: int64): int64 | Vergleicht die Summe aller Positionen (qty × price, in Cent) mit EDI_ORDER_HDR_TOTAL. Toleranz 1 Cent. 0 (= EDI_OK) bei Übereinstimmung, 1 bei Abweichung. Ist TOTAL 0, gibt die Funktion ohne Prüfung 0 zurück. |
ORDRSP — Auftragsbestätigung
| Signatur | Beschreibung |
|---|---|
EdiOrdrspWrite(orderRef: int64, confirmNum: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 | Schreibt ORDRSP mit Positionsstatus (STATUS-Feld der Zeilen: 1=bestätigt, 5=geändert, 7=abgelehnt) |
EdiOrdrspRead(buf: int64, bufLen: int64, hdr: int64, lines: int64, maxLines: int64): int64 | Parst ORDRSP; gibt Zeilenanzahl zurück |
ORDCHG — Änderungsauftrag
| Signatur | Beschreibung |
|---|---|
EdiOrdchgWrite(orderRef: int64, changeNo: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 | Schreibt ORDCHG. changeNo muss mit jeder Änderung erhöht werden (EDIFACT-Pflicht). |
EdiOrdchgRead(buf: int64, bufLen: int64, hdr: int64, lines: int64, maxLines: int64): int64 | Parst ORDCHG; befüllt hdr.EDI_ORDER_HDR_CHANGENO |
Codebeispiel — Auftragsbestätigung schreiben und auswerten
import std.edi.orders;
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;
}
fn main(): int64 {
var lines: int64 := alloc(2 * EDI_ORDER_LINE_SIZE);
var i: int64 := 0;
while (i < 2 * EDI_ORDER_LINE_SIZE) { poke8(lines + i, 0); i := i + 1; }
// Position 1 bestaetigt, Position 2 abgelehnt
poke64(lines + EDI_ORDER_LINE_GTIN, "04012345678901"c as int64);
poke64(lines + EDI_ORDER_LINE_GTINLEN, 14);
poke64(lines + EDI_ORDER_LINE_QTY, 24);
poke64(lines + EDI_ORDER_LINE_LINENO, 1);
poke64(lines + EDI_ORDER_LINE_STATUS, 1);
var l1: int64 := lines + EDI_ORDER_LINE_SIZE;
poke64(l1 + EDI_ORDER_LINE_GTIN, "04012345678918"c as int64);
poke64(l1 + EDI_ORDER_LINE_GTINLEN, 14);
poke64(l1 + EDI_ORDER_LINE_QTY, 0);
poke64(l1 + EDI_ORDER_LINE_LINENO, 2);
poke64(l1 + EDI_ORDER_LINE_STATUS, 7);
// orderRef und confirmNum sind nullterminierte Strings, keine Zahlen
var out: int64 := alloc(4096);
var n: int64 := EdiOrdrspWrite("BST-2026-0815"c, "AB-9001"c, lines, 2, out, 4096);
PrintLn(Feld(out, n));
var hdr2: int64 := alloc(EDI_ORDER_HDR_SIZE);
var lin2: int64 := alloc(8 * EDI_ORDER_LINE_SIZE);
var cnt: int64 := EdiOrdrspRead(out, n, hdr2, lin2, 8);
i := 0;
while (i < cnt) {
var l: int64 := lin2 + i * EDI_ORDER_LINE_SIZE;
var st: int64 := peek64(l + EDI_ORDER_LINE_STATUS);
if (st == 1) { PrintLn(StrConcat("bestaetigt: Position ", IntToStr(peek64(l + EDI_ORDER_LINE_LINENO)))); }
if (st == 7) { PrintLn(StrConcat("abgelehnt: Position ", IntToStr(peek64(l + EDI_ORDER_LINE_LINENO)))); }
i += 1;
}
return 0;
}
BGM+231+AB-9001+9'RFF+ON:BST-2026-0815'LIN+1+1+04012345678901:SRV'QTY+21:24'LIN+2+7+04012345678918:SRV'QTY+21:0'CNT+2:2'
bestaetigt: Position 1
abgelehnt: Position 2
Hinweise
- Änderungsnummer ORDCHG:
EDI_ORDER_HDR_CHANGENOmuss mit jeder neuen ORDCHG inkrementiert werden. Die Gegenseite erkennt damit, ob sie die aktuellste Änderung sieht. - NAD-Rollen:
EdiOrdersReadextrahiert alle vier Rollen. Nicht vorhandene Rollen haben Zeiger 0 und Länge 0. - Gesamtbetrag-Validierung:
EdiOrdersValidateerlaubt 1 Cent Rundungsabweichung. Ohne gesetztenEDI_ORDER_HDR_TOTALprüft sie nichts — wer validieren will, muss den erwarteten Betrag vorher eintragen. - Der Kopf-Gesamtbetrag wird beim Schreiben überschrieben:
EdiOrdersWriterechnetMOA+77selbst aus den Positionen aus. - Strings statt Zahlen bei ORDRSP/ORDCHG:
orderRefundconfirmNumsind Zeiger auf nullterminierten Text ("AB-9001"c as int64); nurchangeNobeiEdiOrdchgWriteist eine echte Zahl. - Structs selbst nullen.
EdiOrdersWriteliest jedes Feld; nicht initialisierter Speicher erzeugt Zufallszeiger.EdiOrdersReadnullt den Kopf dagegen selbst. - Preise und Beträge sind ×100 —
77676bedeutet 776,76 €.
Quelldatei
| Unit | Datei |
|---|---|
std.edi.orders | std/edi/orders.lyx |
Letzte Aktualisierung: 2026-08-13 — beide Beispiele lauffähig gemacht, ausgeführt und um die echten Ausgaben ergänzt (lyxc 1.0.17K); Semantik von EdiOrdersValidate (TOTAL = 0 prüft nichts) und die Zeiger-Parameter von ORDRSP/ORDCHG 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).
