std.edi.transport
Multimodaler Transportauftrag und Sendungsstatus per EDIFACT. Alle 8 Nachrichtentypen teilen denselben Header (EDI_TRN_HDR). IFTMIN beschreibt den vollständigen Transportauftrag mit beliebig vielen Beförderungsabschnitten (Legs). IFTDGN enthält Gefahrgutinformationen (DGD-Struct). IFTSTA übermittelt den Sendungsstatus.
- IFTMIN (BGM 310) — Instruction for the Movement of Goods: Transportauftrag mit Legs
- IFTMBC (BGM 311) — Response to IFTMIN: Auftragsbestätigung/-ablehnung
- IFTMCS (BGM 312) — Instruction Contract Status: Vertragsstatus
- IFTMAN (BGM 313) — Arrival Notice: Ankündigungsmeldung
- IFCSUM (BGM 319) — Freight Invoice: Frachtabrechnung
- IFTSTA (BGM 214) — Status: Sendungsstatus
- IFTDGN (BGM 350) — Dangerous Goods Notification: Gefahrgutmeldung
- IFTFCC (BGM 315) — Freight Costs and other Charges: Frachtkosten (Buchungsreferenz Pflicht)
IFTSTA-Statuscodes:
| Konstante | Wert | Bedeutung |
|---|---|---|
EDI_TRN_STA_PICKEDUP | 1 | Abgeholt |
EDI_TRN_STA_INTRANSIT | 2 | Unterwegs |
EDI_TRN_STA_DELAYED | 3 | Verzögert |
EDI_TRN_STA_DELIVERED | 4 | Zugestellt |
Transportmodi (IFTMIN Legs):
| Wert | Bedeutung |
|---|---|
| 1 | See |
| 2 | Schiene |
| 3 | Straße |
| 4 | Luft |
import std.edi.transport;
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 hdr: int64 := alloc(EDI_TRN_HDR_SIZE);
var i: int64 := 0;
while (i < EDI_TRN_HDR_SIZE) { poke8(hdr + i, 0); i := i + 1; }
poke64(hdr + EDI_TRN_HDR_REF, "TRP-2026-0815"c as int64);
poke64(hdr + EDI_TRN_HDR_REFLEN, 13);
poke64(hdr + EDI_TRN_HDR_DATE, "20260813"c as int64);
poke64(hdr + EDI_TRN_HDR_DATELEN, 8);
poke64(hdr + EDI_TRN_HDR_DEPARTURE, "CNSHA"c as int64);
poke64(hdr + EDI_TRN_HDR_DEPLEN, 5);
poke64(hdr + EDI_TRN_HDR_ARRIVAL, "DEMUC"c as int64);
poke64(hdr + EDI_TRN_HDR_ARRLEN, 5);
poke64(hdr + EDI_TRN_HDR_CARRIER, "Spedition Nord"c as int64);
poke64(hdr + EDI_TRN_HDR_CARRLEN, 14);
poke64(hdr + EDI_TRN_HDR_BOOKINGREF, "BK-99001"c as int64);
poke64(hdr + EDI_TRN_HDR_BOOKINGLEN, 8);
// Drei Teilstrecken: See, Bahn, Strasse
var legs: int64 := alloc(3 * EDI_TRN_LEG_SIZE);
i := 0;
while (i < 3 * EDI_TRN_LEG_SIZE) { poke8(legs + i, 0); i := i + 1; }
poke64(legs + EDI_TRN_LEG_DEPARTURE, "CNSHA"c as int64);
poke64(legs + EDI_TRN_LEG_DEPLEN, 5);
poke64(legs + EDI_TRN_LEG_ARRIVAL, "DEHAM"c as int64);
poke64(legs + EDI_TRN_LEG_ARRLEN, 5);
poke64(legs + EDI_TRN_LEG_MODE, 1); // 1 = See
var g1: int64 := legs + EDI_TRN_LEG_SIZE;
poke64(g1 + EDI_TRN_LEG_DEPARTURE, "DEHAM"c as int64);
poke64(g1 + EDI_TRN_LEG_DEPLEN, 5);
poke64(g1 + EDI_TRN_LEG_ARRIVAL, "DENUE"c as int64);
poke64(g1 + EDI_TRN_LEG_ARRLEN, 5);
poke64(g1 + EDI_TRN_LEG_MODE, 2); // 2 = Bahn
var g2: int64 := legs + 2 * EDI_TRN_LEG_SIZE;
poke64(g2 + EDI_TRN_LEG_DEPARTURE, "DENUE"c as int64);
poke64(g2 + EDI_TRN_LEG_DEPLEN, 5);
poke64(g2 + EDI_TRN_LEG_ARRIVAL, "DEMUC"c as int64);
poke64(g2 + EDI_TRN_LEG_ARRLEN, 5);
poke64(g2 + EDI_TRN_LEG_MODE, 3); // 3 = Strasse
var out: int64 := alloc(4096);
var n: int64 := EdiIftminWrite(hdr, legs, 3, out, 4096);
PrintLn(Feld(out, n));
var hdr2: int64 := alloc(EDI_TRN_HDR_SIZE);
var lg2: int64 := alloc(8 * EDI_TRN_LEG_SIZE);
var cnt: int64 := EdiIftminRead(out, n, hdr2, lg2, 8);
PrintLn(StrConcat("Teilstrecken: ", IntToStr(cnt)));
// Statusmeldung: unterwegs
poke64(hdr + EDI_TRN_HDR_STATUSCODE, EDI_IFTSTA_INTRANSIT);
n := EdiIftstaWrite(hdr, out, 4096);
PrintLn(Feld(out, n));
// Pruef-Funktionen melden Fehler, nicht Erfolg: 0 = in Ordnung
PrintLn(StrConcat("Statuspruefung (0 = ok): ", IntToStr(EdiIftstaStatusCheck(EDI_IFTSTA_INTRANSIT))));
PrintLn(StrConcat("Statuspruefung Code 9: ", IntToStr(EdiIftstaStatusCheck(9))));
PrintLn(StrConcat("IFTFCC-Pruefung (0 = ok): ", IntToStr(EdiIftfccCheck(hdr))));
// Gefahrgutmeldung: Benzin, UN 1203
var dg: int64 := alloc(EDI_DGD_SIZE);
i := 0;
while (i < EDI_DGD_SIZE) { poke8(dg + i, 0); i := i + 1; }
poke64(dg + EDI_DGD_UNNUMBER, "1203"c as int64);
poke64(dg + EDI_DGD_UNLEN, 4);
poke64(dg + EDI_DGD_IMDGCLASS, "3"c as int64);
poke64(dg + EDI_DGD_IMDGLEN, 1);
poke64(dg + EDI_DGD_PACKINGGROUP, 2); // II
poke64(dg + EDI_DGD_EMSCODE, "F-E,S-E"c as int64);
poke64(dg + EDI_DGD_EMSLEN, 7);
poke64(dg + EDI_DGD_QTY, 8000);
if (EdiUnNumberCheck(peek64(dg + EDI_DGD_UNNUMBER), 4) != 1) { PrintLn("UN-Nummer ungueltig"); return 1; }
n := EdiIftdgnWrite(hdr, dg, 1, out, 4096);
PrintLn(Feld(out, n));
return 0;
}
BGM+310+TRP-2026-0815+9'DTM+137:20260813:102'LOC+87+CNSHA::9'LOC+88+DEMUC::9'NAD+CA+Spedition Nord::9'TDT+1++1'LOC+9+CNSHA::9'LOC+11+DEHAM::9'TDT+2++2'LOC+9+DEHAM::9'LOC+11+DENUE::9'TDT+3++3'LOC+9+DENUE::9'LOC+11+DEMUC::9'CNT+2:3'
Teilstrecken: 3
BGM+214+TRP-2026-0815+9'DTM+137:20260813:102'LOC+87+CNSHA::9'LOC+88+DEMUC::9'NAD+CA+Spedition Nord::9'STS+2'CNT+2:1'
Statuspruefung (0 = ok): 0
Statuspruefung Code 9: 1
IFTFCC-Pruefung (0 = ok): 0
BGM+350+TRP-2026-0815+9'DTM+137:20260813:102'LOC+87+CNSHA::9'LOC+88+DEMUC::9'NAD+CA+Spedition Nord::9'DGS+ADR+1203+3+2+F-E,S-E'CNT+2:1'
Jede Teilstrecke wird als TDT-Segment mit Verkehrsträger (1 See, 2 Bahn, 3 Straße, 4 Luft) und den beiden LOC-Segmenten für Abgang und Ziel geschrieben. Status (STS) und Gefahrgut (DGS) nutzen denselben Kopf-Struct.
Imports
std.edi.corestd.alloc
Structs
EdiTrnHdr (EDI_TRN_HDR_SIZE = 112 Bytes)
Gemeinsamer Header für alle 8 Nachrichtentypen.
| Offset-Konstante | Inhalt |
|---|---|
EDI_TRN_HDR_BGMQUAL | BGM-Qualifier (automatisch gesetzt) |
EDI_TRN_HDR_REF / EDI_TRN_HDR_REFLEN | Auftrags-/Dokumentreferenz |
EDI_TRN_HDR_DATE / EDI_TRN_HDR_DATELEN | Datum |
EDI_TRN_HDR_DEPARTURE / EDI_TRN_HDR_DEPARTLEN | Abgangspunkt (LOC+87, z. B. UN/LOCODE) |
EDI_TRN_HDR_ARRIVAL / EDI_TRN_HDR_ARRIVALLEN | Bestimmungsort (LOC+88) |
EDI_TRN_HDR_CARRIER / EDI_TRN_HDR_CARRIERLEN | Spediteur/Carrier (NAD+CA) |
EDI_TRN_HDR_BOOKINGREF / EDI_TRN_HDR_BOOKINGLEN | Buchungsreferenz (RFF+BN) — Pflicht für IFTFCC |
EDI_TRN_HDR_STATUSCODE | IFTSTA-Statuscode (1–4) |
EdiTrnLeg (EDI_TRN_LEG_SIZE = 40 Bytes)
Ein Beförderungsabschnitt innerhalb eines IFTMIN-Auftrags. IFTMIN kann beliebig viele Legs enthalten — z. B. LKW zum Hafen → Schiff → Bahn zu Empfänger.
| Offset-Konstante | Inhalt |
|---|---|
EDI_TRN_LEG_DEPARTURE / EDI_TRN_LEG_DEPARTLEN | Abgangsort des Abschnitts (LOC+9) |
EDI_TRN_LEG_ARRIVAL / EDI_TRN_LEG_ARRIVALLEN | Ankunftsort des Abschnitts (LOC+11) |
EDI_TRN_LEG_MODE | Transportmodus: 1=See, 2=Schiene, 3=Straße, 4=Luft |
Wire pro Leg: TDT+20+mode → LOC+9+departure → LOC+11+arrival.
EdiDgd (EDI_DGD_SIZE = 64 Bytes)
Gefahrgutinformation für IFTDGN. Pro Sendung können mehrere DGD-Strukturen vorkommen.
| Offset-Konstante | Inhalt |
|---|---|
EDI_DGD_UNNUMBER / EDI_DGD_UNNUMLEN | UN-Nummer (genau 4 Stellen, z. B. „1203“ für Benzin) |
EDI_DGD_IMDGCLASS / EDI_DGD_IMDGLEN | IMDG-Klasse (z. B. „3“, „8“, „6.1“) |
EDI_DGD_PACKINGGROUP | Verpackungsgruppe 1–3 (I=höchste, III=niedrigste Gefahr) |
EDI_DGD_EMSCODE / EDI_DGD_EMSLEN | EMS-Code (Emergency Schedule, z. B. „F-E,S-E“) |
EDI_DGD_QTY | Menge in der Sendung |
Wire: DGS+ADR+unNum+imdgClass+packingGroup+emsCode.
Validierungsfunktionen
| Signatur | Beschreibung |
|---|---|
EdiUnNumberCheck(ptr: int64, len: int64): int64 | Prüft UN-Nummer: genau 4 Ziffern (0000–9999). Gibt 1=gültig, 0=ungültig. |
EdiIftstaStatusCheck(code: int64): int64 | Prüft IFTSTA-Statuscode: 1–4 bekannt → 0; sonst 1 (Warnung, nicht Fehler). |
EdiIftfccCheck(hdr: int64): int64 | Gibt 2 (Fehler) wenn keine Buchungsreferenz (RFF+BN) vorhanden — Pflichtfeld in IFTFCC. |
Funktionen
Einfache Transport-Nachrichten
| Write-Funktion | Read-Funktion | Beschreibung |
|---|---|---|
EdiIftmbcWrite(hdr, out, outMax) | EdiIftmbcRead(buf, bufLen, hdr) | IFTMIN-Antwort |
EdiIftmcsWrite(hdr, out, outMax) | EdiIftmcsRead(buf, bufLen, hdr) | Vertragsstatus |
EdiIftmanWrite(hdr, out, outMax) | EdiIftmanRead(buf, bufLen, hdr) | Ankunftsankündigung |
EdiIfcsumWrite(hdr, out, outMax) | EdiIfcsumRead(buf, bufLen, hdr) | Frachtabrechnung |
EdiIftstaWrite(hdr, out, outMax) | EdiIftstaRead(buf, bufLen, hdr) | Sendungsstatus |
EdiIftfccWrite(hdr, out, outMax) | EdiIftfccRead(buf, bufLen, hdr) | Frachtkosten |
Nachrichten mit Leg-Array (IFTMIN)
| Signatur | Beschreibung |
|---|---|
EdiIftminWrite(hdr: int64, legs: int64, legCount: int64, out: int64, outMax: int64): int64 | Schreibt Transportauftrag mit N Beförderungsabschnitten. |
EdiIftminRead(buf: int64, bufLen: int64, hdr: int64, legs: int64, maxLegs: int64): int64 | Parst IFTMIN; gibt Anzahl der Legs zurück. |
Gefahrgutmeldung (IFTDGN)
| Signatur | Beschreibung |
|---|---|
EdiIftdgnWrite(hdr: int64, dgds: int64, dgdCount: int64, out: int64, outMax: int64): int64 | Schreibt Gefahrgutmeldung mit N DGD-Einträgen. |
EdiIftdgnRead(buf: int64, bufLen: int64, hdr: int64, dgds: int64, maxDgds: int64): int64 | Parst IFTDGN; gibt DGD-Anzahl zurück. |
Hinweise
- IFTFCC Buchungsreferenz Pflicht:
EdiIftfccCheckgibt Fehler (2) zurück wenn keine Buchungsreferenz (RFF+BN) gesetzt ist. VorEdiIftfccWriteimmer prüfen. - UN-Nummer immer 4-stellig:
EdiUnNumberCheckverlangt genau 4 Ziffern — also „0012“ statt „12“. Führende Nullen sind Teil der Nummer (z. B. 0004 = Ammoniumnitrat in Lösung). - Prüf-Funktionen melden Fehler, nicht Erfolg:
EdiIftstaStatusCheckliefert 0 für einen bekannten Code und 1 für einen unbekannten;EdiIftfccCheck0 bei gesetzter Buchungsreferenz und 2 ohne. Wer auf== 1als „gültig„ prüft, dreht die Logik um. - Gefahrgut-Struct:
EDI_DGD_PACKINGGROUPist eine Zahl (1 = I, 2 = II, 3 = III), UN-Nummer und IMDG-Klasse dagegen Zeiger auf Text. Alles landet in einemDGS+ADR-Segment. - Legs nur in IFTMIN: Nur
EdiIftminWrite/Readakzeptiert ein Leg-Array. Alle anderen Nachrichten haben genau einen Abgangspunkt und einen Bestimmungsort im Header.
Quelldatei
| Unit | Datei |
|---|---|
std.edi.transport | std/edi/transport.lyx |
Letzte Aktualisierung: 2026-08-13 — ein durchgehendes, lauffähiges Beispiel für IFTMIN (drei Teilstrecken), IFTSTA und IFTDGN mit echter Ausgabe (lyxc 1.0.17K); Rückgabekonvention der Prüf-Funktionen (0 = ok) richtiggestellt
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).
