====== std.edi.customs ====== Zoll-Nachrichten per EDIFACT für den grenzüberschreitenden Warenverkehr. Alle vier Nachrichtentypen teilen denselben Header (EDI_CUS_HDR) mit Absender, Empfänger, Herkunfts-/Zielort, Zollbehörde-Referenz und Zollwert. * **CUSCAR** (BGM 85) — Customs Cargo Report: Carrier meldet Ladung bei Zollbehörde * **CUSDEC** (BGM 960) — Customs Declaration: Anmeldung durch Zollanmelder * **CUSEXP** (BGM 962) — Customs Express: Express-Sendungsmanifest (Kurier) * **CUSRSP** (BGM 961) — Customs Response: Antwort der Zollbehörde CUSRSP-Statuscodes: ^ Konstante ^ Wert ^ Bedeutung ^ | ''EDI_CUSRSP_ACCEPTED'' | 1 | Anmeldung akzeptiert | | ''EDI_CUSRSP_REJECTED'' | 2 | Anmeldung abgelehnt | | ''EDI_CUSRSP_QUERIED'' | 3 | Rückfrage / weitere Informationen benötigt | | ''EDI_CUSRSP_RELEASED'' | 4 | Waren freigegeben | import std.edi.customs; 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_CUS_HDR_SIZE); var i: int64 := 0; while (i < EDI_CUS_HDR_SIZE) { poke8(hdr + i, 0); i := i + 1; } poke64(hdr + EDI_CUS_HDR_REF, "ZOLL-2026-0042"c as int64); poke64(hdr + EDI_CUS_HDR_REFLEN, 14); poke64(hdr + EDI_CUS_HDR_DATE, "20260813"c as int64); poke64(hdr + EDI_CUS_HDR_DATELEN, 8); poke64(hdr + EDI_CUS_HDR_ORIGIN, "CNSHA"c as int64); // Shanghai poke64(hdr + EDI_CUS_HDR_ORIGLEN, 5); poke64(hdr + EDI_CUS_HDR_DEST, "DEHAM"c as int64); // Hamburg poke64(hdr + EDI_CUS_HDR_DESTLEN, 5); poke64(hdr + EDI_CUS_HDR_DECLARANT, "Muster Handel GmbH"c as int64); poke64(hdr + EDI_CUS_HDR_DECLLEN, 18); poke64(hdr + EDI_CUS_HDR_CARRIER, "Reederei Nord"c as int64); poke64(hdr + EDI_CUS_HDR_CARRLEN, 13); poke64(hdr + EDI_CUS_HDR_CUSTVALUE, 1250000); // 12.500,00 EUR poke64(hdr + EDI_CUS_HDR_CURRENCY, "EUR"c as int64); poke64(hdr + EDI_CUS_HDR_CURLEN, 3); poke64(hdr + EDI_CUS_HDR_PROCCODE, 4000); // Ueberfuehrung freier Verkehr var items: int64 := alloc(2 * EDI_CUS_ITEM_SIZE); i := 0; while (i < 2 * EDI_CUS_ITEM_SIZE) { poke8(items + i, 0); i := i + 1; } poke64(items + EDI_CUS_ITEM_DESC, "Kaffee geroestet"c as int64); poke64(items + EDI_CUS_ITEM_DESCLEN, 16); poke64(items + EDI_CUS_ITEM_QTY, 500); poke64(items + EDI_CUS_ITEM_VALUE, 900000); poke64(items + EDI_CUS_ITEM_HSCODE, "09012100"c as int64); poke64(items + EDI_CUS_ITEM_HSCODELEN, 8); var it1: int64 := items + EDI_CUS_ITEM_SIZE; poke64(it1 + EDI_CUS_ITEM_DESC, "Teemischung"c as int64); poke64(it1 + EDI_CUS_ITEM_DESCLEN, 11); poke64(it1 + EDI_CUS_ITEM_QTY, 200); poke64(it1 + EDI_CUS_ITEM_VALUE, 350000); poke64(it1 + EDI_CUS_ITEM_HSCODE, "09024000"c as int64); poke64(it1 + EDI_CUS_ITEM_HSCODELEN, 8); var out: int64 := alloc(4096); var n: int64 := EdiCusdecWrite(hdr, items, 2, out, 4096); PrintLn(Feld(out, n)); var hdr2: int64 := alloc(EDI_CUS_HDR_SIZE); var it2: int64 := alloc(8 * EDI_CUS_ITEM_SIZE); var cnt: int64 := EdiCusdecRead(out, n, hdr2, it2, 8); PrintLn(StrConcat(StrConcat("Positionen: ", IntToStr(cnt)), StrConcat(" Zollwert/100: ", IntToStr(peek64(hdr2 + EDI_CUS_HDR_CUSTVALUE))))); // Behoerdenantwort: Ware freigegeben var rsp: int64 := alloc(EDI_CUS_HDR_SIZE); i := 0; while (i < EDI_CUS_HDR_SIZE) { poke8(rsp + i, 0); i := i + 1; } poke64(rsp + EDI_CUS_HDR_REF, "RSP-2026-0042"c as int64); poke64(rsp + EDI_CUS_HDR_REFLEN, 13); poke64(rsp + EDI_CUS_HDR_DECLREF, "ZOLL-2026-0042"c as int64); poke64(rsp + EDI_CUS_HDR_DECLREFLEN, 14); poke64(rsp + EDI_CUS_HDR_RSPCODE, EDI_CUSRSP_RELEASED); n := EdiCusrspWrite(rsp, out, 4096); PrintLn(Feld(out, n)); var rsp2: int64 := alloc(EDI_CUS_HDR_SIZE); EdiCusrspRead(out, n, rsp2); var code: int64 := peek64(rsp2 + EDI_CUS_HDR_RSPCODE); if (code == EDI_CUSRSP_RELEASED) { PrintLn("Ware freigegeben"); } if (code == EDI_CUSRSP_REJECTED) { PrintLn("Anmeldung abgelehnt"); } return 0; } BGM+960+ZOLL-2026-0042+9'DTM+137:20260813:102'LOC+87+CNSHA::9'LOC+88+DEHAM::9'NAD+DT+Muster Handel GmbH::9'NAD+CA+Reederei Nord::9'CUX+2:EUR:4'MOA+126:12500.00'GIS+4000'LIN+1+Kaffee geroestet'QTY+1:500'MOA+66:9000.00'RFF+HS:09012100'LIN+2+Teemischung'QTY+1:200'MOA+66:3500.00'RFF+HS:09024000'CNT+2:2' Positionen: 2 Zollwert/100: 1250000 BGM+961+RSP-2026-0042+9'RFF+ADE:ZOLL-2026-0042'STS+4'CNT+2:1' Ware freigegeben ''LOC+87'' ist der Abgangs-, ''LOC+88'' der Bestimmungsort (UN/LOCODE), ''GIS'' trägt den Zollverfahrenscode, ''MOA+126'' den Gesamt- und ''MOA+66'' den Positionszollwert. Die Behördenantwort besteht aus ''RFF+ADE'' (Bezug zur Anmeldung) und ''STS'' mit dem Statuscode. ---- ===== Imports ===== * ''std.edi.core'' * ''std.alloc'' ---- ===== Structs ===== ==== EdiCusHdr (EDI_CUS_HDR_SIZE = 160 Bytes) ==== ^ Offset-Konstante ^ Inhalt ^ | ''EDI_CUS_HDR_BGMQUAL'' | BGM-Qualifier (''EDI_CUS_BGM_*'') | | ''EDI_CUS_HDR_REF / EDI_CUS_HDR_REFLEN'' | Referenz/Dokumentnummer | | ''EDI_CUS_HDR_DATE / EDI_CUS_HDR_DATELEN'' | Datum | | ''EDI_CUS_HDR_ORIGIN / EDI_CUS_HDR_ORIGLEN'' | Herkunftsland (LOC+87, z. B. "CN") | | ''EDI_CUS_HDR_DEST / EDI_CUS_HDR_DESTLEN'' | Bestimmungsland (LOC+88, z. B. "DE") | | ''EDI_CUS_HDR_DECLARANT / EDI_CUS_HDR_DECLLEN'' | Zollanmelder (NAD+DT) | | ''EDI_CUS_HDR_CARRIER / EDI_CUS_HDR_CARRLEN'' | Beförderer (NAD+CA) | | ''EDI_CUS_HDR_CUSTVALUE'' | Zollwert × 100 (MOA+126) | | ''EDI_CUS_HDR_CURRENCY / EDI_CUS_HDR_CURLEN'' | Währungscode | | ''EDI_CUS_HDR_DECLREF / EDI_CUS_HDR_DECLREFLEN'' | Zollanmeldungsnummer (RFF+ADE) | | ''EDI_CUS_HDR_RSPCODE'' | CUSRSP-Statuscode (1–4) | | ''EDI_CUS_HDR_PROCCODE'' | Zollverfahrenscode | ==== EdiCusItem (EDI_CUS_ITEM_SIZE = 48 Bytes) ==== ^ Offset-Konstante ^ Inhalt ^ | ''EDI_CUS_ITEM_DESC / EDI_CUS_ITEM_DESCLEN'' | Warenbeschreibung (LIN) | | ''EDI_CUS_ITEM_QTY'' | Menge | | ''EDI_CUS_ITEM_VALUE'' | Positionswert × 100 (MOA+66) | | ''EDI_CUS_ITEM_HSCODE / EDI_CUS_ITEM_HSCODELEN'' | HS-Zolltarifnummer (RFF+HS) | ---- ===== Funktionen ===== ^ Write-Funktion ^ Read-Funktion ^ Beschreibung ^ | ''EdiCuscarWrite(hdr, items, itemCount, out, outMax)'' | ''EdiCuscarRead(buf, bufLen, hdr, items, maxItems)'' | Cargo Report | | ''EdiCusdecWrite(hdr, items, itemCount, out, outMax)'' | ''EdiCusdecRead(buf, bufLen, hdr, items, maxItems)'' | Zollanmeldung | | ''EdiCusexpWrite(hdr, items, itemCount, out, outMax)'' | ''EdiCusexpRead(buf, bufLen, hdr, items, maxItems)'' | Express-Manifest | | ''EdiCusrspWrite(hdr, out, outMax)'' | ''EdiCusrspRead(buf, bufLen, hdr)'' | Zollantwort (kein Item-Array) | Alle Write-Funktionen setzen automatisch den BGM-Qualifier. Read-Funktionen geben die Anzahl der Items zurück (für CUSRSP: 1=ok, 0=Fehler). ---- ===== Hinweise ===== * **HS-Code (RFF+HS)**: Die 6- bis 10-stellige HS-Zolltarifnummer identifiziert die Warengruppe international. Korrekte HS-Codes sind Voraussetzung für den automatisierten Zollabschluss. * **Zollwert (MOA+126)**: Muss in der Währung aus CUX angegeben werden. Festkomma × 100. * **CUSRSP ohne Items**: ''EdiCusrspWrite/Read'' hat kein Item-Array — die Antwort bezieht sich immer auf die gesamte Anmeldung. Pflichtfelder sind ''EDI_CUS_HDR_DECLREF'' (Bezug zur Anmeldung) und ''EDI_CUS_HDR_RSPCODE''. * **Statuscodes der Antwort**: ''EDI_CUSRSP_ACCEPTED'' (1) angenommen, ''EDI_CUSRSP_REJECTED'' (2) abgelehnt, ''EDI_CUSRSP_QUERIED'' (3) Rückfrage, ''EDI_CUSRSP_RELEASED'' (4) Ware freigegeben. * **BGM-Qualifier setzt die Bibliothek selbst**: ''EdiCuscarWrite'' schreibt 85, ''EdiCusdecWrite'' 960, ''EdiCusexpWrite'' 962, ''EdiCusrspWrite'' 961 — ein selbst gesetzter ''EDI_CUS_HDR_BGMQUAL'' wird überschrieben. Alle vier Nachrichten teilen sich denselben Kopf-Struct. * **Alle vier Nachrichten nutzen dieselben Item-Structs**; für CUSCAR (Frachtanmeldung) ist die Warenbeschreibung Pflicht, für CUSDEC zusätzlich der HS-Code. ---- ===== Quelldatei ===== ^ Unit ^ Datei ^ | ''std.edi.customs'' | ''std/edi/customs.lyx'' | Letzte Aktualisierung: 2026-08-13 — ein durchgehendes, lauffähiges Beispiel (Zollanmeldung → Behördenantwort) mit echter Ausgabe (lyxc 1.0.17K); Statuscodes und das automatische Setzen des BGM-Qualifiers dokumentiert 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).