Lieferschein und Wareneingangsbestätigung per EDIFACT. DESADV bildet die dreistufige Verpackungshierarchie (Palette → Karton → Artikel) über die EDIFACT-Segmente CPS/PAC/GIN/LIN ab. Jedes Packstück trägt eine SSCC-18-Nummer zur lückenlosen Rückverfolgung.
SSCC-18-Funktionen:
EdiSsccCheck — Prüft Prüfziffer (GS1 Mod-10)EdiSsccGenerate — Berechnet Prüfziffer aus 17-stelliger Basis
import std.edi.shipping;
import std.alloc;
import std.string;
fn main(): int64 {
// 17 Stellen: Erweiterungsziffer + GS1-Basisnummer + laufende Nummer
var sscc: int64 := alloc(19); // 18 Ziffern + NUL
EdiSsccGenerate("34012345000000001"c, sscc);
PrintLn(StrConcat("SSCC: ", sscc as pchar));
PrintLn(StrConcat("Pruefziffer ok: ", IntToStr(EdiSsccCheck(sscc as pchar, 18))));
free(sscc, 19);
return 0;
}
SSCC: 340123450000000017
Pruefziffer ok: 1
std.edi.corestd.alloc| Konstante | Wert | Bedeutung |
|---|---|---|
EDI_PKG_PALLET | 1 | Palette (CPS+PAC mit Code 201) |
EDI_PKG_CARTON | 2 | Karton (CPS+PAC mit Code CT) |
EDI_PKG_ITEM | 3 | Artikel-Ebene (CPS+LIN+QTY) |
| Offset-Konstante | Inhalt |
|---|---|
EDI_PACKAGE_SSCC / EDI_PACKAGE_SSCCLEN | SSCC-Zeiger (18 Zeichen) und -Länge |
EDI_PACKAGE_TYPE | Pakettyp: EDI_PKG_PALLET / EDI_PKG_CARTON / EDI_PKG_ITEM |
EDI_PACKAGE_PARENT | Index des übergeordneten Packstücks (0-basiert); -1 wenn keins |
EDI_PACKAGE_GTIN / EDI_PACKAGE_GTINLEN | GTIN (nur bei Items) |
EDI_PACKAGE_QTY | Menge (nur bei Items) |
Reihenfolge beim Schreiben: Erst alle Paletten, dann Kartons, dann Artikel. Der Parent-Index verweist auf den 0-basierten Index im Array.
| Offset-Konstante | Inhalt |
|---|---|
EDI_RECADV_LINE_GTIN / EDI_RECADV_LINE_GTINLEN | GTIN-Zeiger und -Länge |
EDI_RECADV_LINE_ORDERED | Bestellte Menge (QTY+21) |
EDI_RECADV_LINE_DELIVERED | Gelieferte Menge (QTY+12) |
EDI_RECADV_LINE_ACCEPTED | Akzeptierte Menge (QTY+192) |
EDI_RECADV_LINE_REASON / EDI_RECADV_LINE_REASONLEN | Abweichungsgrund als Freitext (FTX+AAI, optional; 0 wenn keiner) |
| Signatur | Beschreibung |
|---|---|
EdiSsccCheck(ptr: int64, len: int64): int64 | Prüft SSCC-18-Prüfziffer (GS1 Mod-10). Gibt 1=gültig, 0=ungültig. Erwartet exakt 18 Stellen. |
EdiSsccGenerate(base17: int64, out: int64): void | Berechnet Prüfziffer aus 17-stelliger Basis-SSCC. Schreibt 18 Stellen + NUL in out (mind. 19 Bytes). |
| Signatur | Beschreibung |
|---|---|
EdiDesadvWrite(refNum: int64, date: int64, packages: int64, packCount: int64, out: int64, outMax: int64): int64 | Schreibt DESADV. Pakete müssen in Hierarchie-Reihenfolge vorliegen (Paletten → Kartons → Items). |
EdiDesadvRead(buf: int64, bufLen: int64, packages: int64, maxPacks: int64): int64 | Parst DESADV; gibt Paketanzahl zurück oder -1 bei doppelter SSCC. |
| Signatur | Beschreibung |
|---|---|
EdiRecadvWrite(orderRef: int64, date: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 | Schreibt RECADV mit Kreuzreferenz auf Bestellnummer (RFF+ON). |
EdiRecadvRead(buf: int64, bufLen: int64, lines: int64, maxLines: int64): int64 | Parst RECADV; gibt Zeilenanzahl zurück. |
import std.edi.shipping;
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 {
// SSCC aus 17 Stellen erzeugen (Prüfziffer haengt die Bibliothek an)
var ssccPal: int64 := alloc(19);
var ssccKar: int64 := alloc(19);
EdiSsccGenerate("34012345000000001"c, ssccPal);
EdiSsccGenerate("34012345000000002"c, ssccKar);
// Hierarchie: Palette -> Karton -> Artikel
var pk: int64 := alloc(3 * EDI_PACKAGE_SIZE);
var i: int64 := 0;
while (i < 3 * EDI_PACKAGE_SIZE) { poke8(pk + i, 0); i := i + 1; }
var p0: int64 := pk;
poke64(p0 + EDI_PACKAGE_SSCC, ssccPal);
poke64(p0 + EDI_PACKAGE_SSCCLEN, 18);
poke64(p0 + EDI_PACKAGE_TYPE, EDI_PKG_PALLET);
poke64(p0 + EDI_PACKAGE_PARENT, 0 - 1);
var p1: int64 := pk + EDI_PACKAGE_SIZE;
poke64(p1 + EDI_PACKAGE_SSCC, ssccKar);
poke64(p1 + EDI_PACKAGE_SSCCLEN, 18);
poke64(p1 + EDI_PACKAGE_TYPE, EDI_PKG_CARTON);
poke64(p1 + EDI_PACKAGE_PARENT, 0); // haengt an Paket 0
var p2: int64 := pk + 2 * EDI_PACKAGE_SIZE;
poke64(p2 + EDI_PACKAGE_TYPE, EDI_PKG_ITEM);
poke64(p2 + EDI_PACKAGE_PARENT, 1); // liegt im Karton
poke64(p2 + EDI_PACKAGE_GTIN, "04012345678901"c as int64);
poke64(p2 + EDI_PACKAGE_GTINLEN, 14);
poke64(p2 + EDI_PACKAGE_QTY, 24);
var out: int64 := alloc(4096);
var n: int64 := EdiDesadvWrite("LS-2026-0815"c, "20260813"c, pk, 3, out, 4096);
PrintLn(Feld(out, n));
var pk2: int64 := alloc(16 * EDI_PACKAGE_SIZE);
var cnt: int64 := EdiDesadvRead(out, n, pk2, 16);
PrintLn(StrConcat("Packstuecke: ", IntToStr(cnt)));
i := 0;
while (i < cnt) {
var p: int64 := pk2 + i * EDI_PACKAGE_SIZE;
PrintLn(StrConcat(StrConcat(" Typ ", IntToStr(peek64(p + EDI_PACKAGE_TYPE))),
StrConcat(" Parent ", IntToStr(peek64(p + EDI_PACKAGE_PARENT)))));
i += 1;
}
// RECADV: 24 bestellt, 24 geliefert, 22 angenommen
var rl: int64 := alloc(EDI_RECADV_LINE_SIZE);
i := 0;
while (i < EDI_RECADV_LINE_SIZE) { poke8(rl + i, 0); i := i + 1; }
poke64(rl + EDI_RECADV_LINE_GTIN, "04012345678901"c as int64);
poke64(rl + EDI_RECADV_LINE_GTINLEN, 14);
poke64(rl + EDI_RECADV_LINE_ORDERED, 24);
poke64(rl + EDI_RECADV_LINE_DELIVERED, 24);
poke64(rl + EDI_RECADV_LINE_ACCEPTED, 22);
poke64(rl + EDI_RECADV_LINE_REASON, "2 Packungen beschaedigt"c as int64);
poke64(rl + EDI_RECADV_LINE_REASONLEN, 23);
n := EdiRecadvWrite("BST-2026-0815"c, "20260814"c, rl, 1, out, 4096);
PrintLn(Feld(out, n));
return 0;
}
BGM+351+LS-2026-0815+9'DTM+137:20260813:102'CPS+1'PAC+1++201'PCI+33E'GIN+BJ+340123450000000017'CPS+2+1'PAC+1++CT'PCI+33E'GIN+BJ+340123450000000024'CPS+3+2'LIN+1++04012345678901:SRV'QTY+12:24'CNT+2:3'
Packstuecke: 3
Typ 1 Parent -1
Typ 2 Parent 0
Typ 3 Parent 1
BGM+632+BST-2026-0815+9'DTM+137:20260814:102'RFF+ON:BST-2026-0815'LIN+1++04012345678901:SRV'QTY+21:24'QTY+12:24'QTY+192:22'FTX+AAI+++2 Packungen beschaedigt'CNT+2:1'
Die Hierarchie steckt in den CPS-Segmenten: CPS+1 ist die Palette (ohne Elternangabe), CPS+2+1 der Karton darunter, CPS+3+2 die Artikelebene. Beim Lesen steht die Elternbeziehung als 0-basierter Index in EDI_PACKAGE_PARENT, -1 bei der obersten Ebene.
Im RECADV stehen drei Mengen nebeneinander: QTY+21 bestellt, QTY+12 geliefert, QTY+192 angenommen — die Differenz begründet das FTX-Segment.
EdiDesadvRead gibt -1 zurück, wenn dieselbe SSCC-Nummer zweimal im selben Lieferschein steht. Der Rückgabewert ist sonst die Zahl der Packstücke — vor dem Durchlaufen also auf < 0 prüfen.EdiSsccGenerate erwartet genau 17 Stellen und schreibt 18 Ziffern plus Nullbyte (Puffer ≥ 19 Bytes). EdiDesadvWrite prüft die SSCC nicht — wer ungeprüfte Nummern einträgt, verschickt sie auch.EDI_PKG_ITEM bleiben SSCC-Zeiger und -Länge 0; dafür sind GTIN und Menge Pflicht.EDI_PKG_PALLET) vor Kartons und Artikel kommen. Das entspricht der CPS-Reihenfolge in EDIFACT.EdiRecadvWrite setzt automatisch RFF+ON mit dem orderRef-Wert. So kann die Gegenseite Wareneingang und Bestellung zuordnen.| Unit | Datei |
|---|---|
std.edi.shipping | std/edi/shipping.lyx |
Letzte Aktualisierung: 2026-08-13 — das defekte SSCC-Beispiel (fehlerhaftes StrConcat) ersetzt, DESADV-Beispiel um den RECADV-Teil erweitert; beide lauffähig, ausgeführt und mit echter Ausgabe belegt (lyxc 1.0.17K)
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).