====== std.edi.seafreight ======
Seefrachtsteuerung per EDIFACT: Stauplan, Containeranweisungen, Bekanntmachungen und Gewichtsangaben. Alle 9 Nachrichtentypen verwenden denselben Header (EDI_SF_HDR) und dieselbe Containerstruktur (EDI_SF_CONT_SIZE = 80 Bytes). Container-IDs werden nach ISO 6346 (11-stellig) validiert.
* **BAPLIE** (BGM 23) — Bay Plan with Loading Information: Stauplan des Schiffes (Position je Container)
* **MOVINS** (BGM 28) — Stowage Instruction: Staupläne für Be-/Entladung
* **COPARN** (BGM 38) — Container Pre-Arrival Notification: Anmeldung vor Einlauf
* **CODECO** (BGM 29) — Container Gate-In/-Out: Ein-/Ausgangsmeldung am Terminal
* **COARRI** (BGM 30) — Container Arrival/Departure: Ankunfts-/Abfahrtsmeldung
* **COPINO** (BGM 39) — Container Pre-Notification: Voranmeldung für Pick-up
* **COPRAR** (BGM 42) — Container Pre-Advice of Release: Freigabemitteilung
* **VERMAS** (BGM 35) — Verified Mass: Verifiziertes Bruttogewicht (VGM, SOLAS-Pflicht)
* **HANMOV** (BGM 85) — Handling Movement: Umschlagsanweisung (Shift/Transfer)
Bewegungstypen:
^ Konstante ^ Wert ^ Bedeutung ^
| ''EDI_SF_MOVE_LOAD'' | 1 | Verladen |
| ''EDI_SF_MOVE_DISCHARGE'' | 2 | Entladen |
| ''EDI_SF_MOVE_SHIFT'' | 3 | Umlagern |
import std.edi.seafreight;
// VERMAS — Verifiziertes Containergewicht (SOLAS VGM)
var hdr: int64 := alloc(EDI_SF_HDR_SIZE);
poke64(hdr + EDI_SF_HDR_REF, "VGM-2026-001" as int64);
poke64(hdr + EDI_SF_HDR_REFLEN, 12);
poke64(hdr + EDI_SF_HDR_DATE, "20261201" as int64);
poke64(hdr + EDI_SF_HDR_VESSEL, "EVER GIVEN" as int64);
poke64(hdr + EDI_SF_HDR_VESSELLN, 10);
poke64(hdr + EDI_SF_HDR_VOYAGE, "VY2026-48E" as int64);
poke64(hdr + EDI_SF_HDR_VOYAGELN, 10);
poke64(hdr + EDI_SF_HDR_PORT, "DEHAM" as int64); // Hamburg UNLOCODE
poke64(hdr + EDI_SF_HDR_PORTLEN, 5);
var conts: int64 := alloc(EDI_SF_CONT_SIZE);
poke64(conts + EDI_SF_CONT_ID, "TCKU3425678" as int64); // ISO 6346, 11 Zeichen
poke64(conts + EDI_SF_CONT_IDLEN, 11);
poke64(conts + EDI_SF_CONT_SIZE_FT, 20); // 20-Fuß-Container (TEU)
poke64(conts + EDI_SF_CONT_TYPE, "GP" as int64);
poke64(conts + EDI_SF_CONT_TYPELEN, 2);
poke64(conts + EDI_SF_CONT_WEIGHT, 2241500); // 22415,00 kg × 100
var out: int64 := alloc(4096);
var n: int64 := EdiVermasWrite(hdr, conts, 1, out, 4096);
free(conts, EDI_SF_CONT_SIZE);
free(hdr, EDI_SF_HDR_SIZE);
free(out, 4096);
----
===== Imports =====
* ''std.edi.core''
* ''std.alloc''
----
===== Structs =====
==== EdiSfHdr (EDI_SF_HDR_SIZE = 96 Bytes) ====
^ Offset-Konstante ^ Inhalt ^
| ''EDI_SF_HDR_BGMQUAL'' | BGM-Qualifier (automatisch gesetzt) |
| ''EDI_SF_HDR_REF / EDI_SF_HDR_REFLEN'' | Dokumentreferenz |
| ''EDI_SF_HDR_DATE / EDI_SF_HDR_DATELEN'' | Datum |
| ''EDI_SF_HDR_VESSEL / EDI_SF_HDR_VESSELLN'' | Schiffsname (TDT+20) |
| ''EDI_SF_HDR_VOYAGE / EDI_SF_HDR_VOYAGELN'' | Reise-/Voyage-Nummer (RFF+VN) |
| ''EDI_SF_HDR_PORT / EDI_SF_HDR_PORTLEN'' | Hafen (LOC+9, UN/LOCODE) |
| ''EDI_SF_HDR_MOVECOUNT'' | Anzahl Container (CNT) |
==== EdiSfContainer (EDI_SF_CONT_SIZE = 80 Bytes) ====
^ Offset-Konstante ^ Inhalt ^
| ''EDI_SF_CONT_ID / EDI_SF_CONT_IDLEN'' | Container-ID nach ISO 6346 (11 Zeichen) |
| ''EDI_SF_CONT_SIZE_FT'' | Containermaß in Fuß (z. B. 20, 40, 45) |
| ''EDI_SF_CONT_TYPE / EDI_SF_CONT_TYPELEN'' | ISO-Containertyp-Code (z. B. "GP", "RF", "OT") |
| ''EDI_SF_CONT_BAY'' | Bay-Position (Ladeposition im Schiff) |
| ''EDI_SF_CONT_ROW'' | Row-Position |
| ''EDI_SF_CONT_TIER'' | Tier-Position |
| ''EDI_SF_CONT_WEIGHT'' | Bruttogewicht × 100 in kg (MEA+VGM+WT:KGM) |
| ''EDI_SF_CONT_MOVETYPE'' | Bewegungstyp: 1=Load, 2=Discharge, 3=Shift |
Wire-Format pro Container: ''EQD+CN+id+size:type'' → ''LOC+147+bay:row:tier'' → ''MEA+VGM+WT:KGM+weight'' → ''TSR+moveType''.
----
===== ISO 6346 Container-Validierung =====
^ Signatur ^ Beschreibung ^
| ''EdiContainerCheck(ptr: int64, len: int64): int64'' | Prüft ISO-6346-Prüfziffer (11-stellig). Buchstaben A–Z werden auf 10–35 abgebildet (11/22/33 übersprungen); Gewichte 2⁰…2⁹; Prüfziffer = (Summe % 11) % 10. Gibt 1=gültig, 0=ungültig. |
ISO-6346-Format: 4 Buchstaben Prefix (z. B. "TCKU") + 6 Ziffern Seriennummer + 1 Prüfziffer, z. B. ''TCKU342567**8**''.
----
===== Funktionen =====
Alle 9 Nachrichtentypen teilen dieselbe Signatur:
^ Write-Funktion ^ Read-Funktion ^ Beschreibung ^
| ''EdiBaplieWrite(hdr, conts, contCount, out, outMax)'' | ''EdiBaplieRead(buf, bufLen, hdr, conts, maxConts)'' | Stauplan |
| ''EdiMovinsWrite(hdr, conts, contCount, out, outMax)'' | ''EdiMovinsRead(buf, bufLen, hdr, conts, maxConts)'' | Staupläne Be-/Entladung |
| ''EdiCoparnWrite(hdr, conts, contCount, out, outMax)'' | ''EdiCoparnRead(buf, bufLen, hdr, conts, maxConts)'' | Voranmeldung Einlauf |
| ''EdiCodecoWrite(hdr, conts, contCount, out, outMax)'' | ''EdiCodecoRead(buf, bufLen, hdr, conts, maxConts)'' | Gate-In/-Out |
| ''EdiCoarriWrite(hdr, conts, contCount, out, outMax)'' | ''EdiCoarriRead(buf, bufLen, hdr, conts, maxConts)'' | Ankunfts-/Abfahrtsmeldung |
| ''EdiCopinoWrite(hdr, conts, contCount, out, outMax)'' | ''EdiCopinoRead(buf, bufLen, hdr, conts, maxConts)'' | Voranmeldung Pick-up |
| ''EdiCoprarWrite(hdr, conts, contCount, out, outMax)'' | ''EdiCoprarRead(buf, bufLen, hdr, conts, maxConts)'' | Freigabemitteilung |
| ''EdiVermasWrite(hdr, conts, contCount, out, outMax)'' | ''EdiVermasRead(buf, bufLen, hdr, conts, maxConts)'' | VGM-Gewicht (SOLAS) |
| ''EdiHanmovWrite(hdr, conts, contCount, out, outMax)'' | ''EdiHanmovRead(buf, bufLen, hdr, conts, maxConts)'' | Umschlagsanweisung |
Alle Read-Funktionen geben die Anzahl der gelesenen Container zurück. Zero-Copy: Zeiger in ''conts'' zeigen in ''buf''.
----
===== Codebeispiel — BAPLIE Stauplan lesen =====
import std.edi.seafreight;
var maxConts: int64 := 1000;
var hdr: int64 := alloc(EDI_SF_HDR_SIZE);
var conts: int64 := alloc(maxConts * EDI_SF_CONT_SIZE);
var count: int64 := EdiBaplieRead(inBuf, inBufLen, hdr, conts, maxConts);
var i: int64 := 0;
while (i < count) {
var c: int64 := conts + i * EDI_SF_CONT_SIZE;
// ISO 6346 Validierung jedes Containers
var id: int64 := peek64(c + EDI_SF_CONT_ID);
var ilen:int64 := peek64(c + EDI_SF_CONT_IDLEN);
if (EdiContainerCheck(id, ilen) == 0) {
PrintLn("Ungültige Container-ID: " + (id as pchar));
}
var bay: int64 := peek64(c + EDI_SF_CONT_BAY);
var row: int64 := peek64(c + EDI_SF_CONT_ROW);
var tier:int64 := peek64(c + EDI_SF_CONT_TIER);
PrintLn("Slot: " + IntToStr(bay) + "/" + IntToStr(row) + "/" + IntToStr(tier));
i := i + 1;
}
free(conts, maxConts * EDI_SF_CONT_SIZE);
free(hdr, EDI_SF_HDR_SIZE);
----
===== Hinweise =====
* **VGM SOLAS-Pflicht**: Seit 2016 müssen alle Container vor Verladung ein verifiziertes Bruttogewicht (VGM) vorweisen. ''EdiVermasWrite'' erzeugt den entsprechenden EDIFACT-Austausch.
* **Bay/Row/Tier**: Die Stauposition in BAPLIE/MOVINS wird als dreistellige Ortsangabe kodiert (LOC+147). Bay = Schiffslängsachse, Row = Querachse, Tier = Höhe.
* **CODECO Ein-/Ausgang**: Beim Gate-In wird ''EDI_SF_MOVE_LOAD'' verwendet, beim Gate-Out ''EDI_SF_MOVE_DISCHARGE''. ''EDI_SF_MOVE_SHIFT'' steht für interne Terminalumlagerungen.
* **UN/LOCODE Häfen**: ''EDI_SF_HDR_PORT'' erwartet einen 5-stelligen UN/LOCODE (z. B. "DEHAM" = Hamburg, "CNSHA" = Shanghai).
----
===== Quelldatei =====
^ Unit ^ Datei ^
| ''std.edi.seafreight'' | ''std/edi/seafreight.lyx'' |
Letzte Aktualisierung: 2026-06-16