====== 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