Stammdaten-Austausch per EDIFACT: Artikelkataloge mit Preisen und Gültigkeitszeiträumen (PRICAT) sowie Partnerdaten mit GLN-Adressen (PARTIN). GS1-Validierungsfunktionen für GTIN und GLN sind in dieser Unit enthalten.
GS1-Validierungen:
| Funktion | Unterstützte Längen | Algorithmus |
|---|---|---|
EdiGtinCheck | 8, 12, 13, 14 Stellen | GS1 Mod-10 (Prüfziffer) |
EdiGlnCheck | 13 Stellen | GS1 Mod-10 |
Achtung: EdiPricatWrite validiert GTINs nicht — das liegt in der Verantwortung des Callers.
import std.edi.catalog;
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 items: int64 := alloc(2 * EDI_PRICAT_ITEM_SIZE);
var i: int64 := 0;
while (i < 2 * EDI_PRICAT_ITEM_SIZE) { poke8(items + i, 0); i := i + 1; }
var a: int64 := items;
poke64(a + EDI_PRICAT_GTIN, "04012345678901"c as int64);
poke64(a + EDI_PRICAT_GTINLEN, 14);
poke64(a + EDI_PRICAT_DESC, "Kaffee gemahlen 500g"c as int64);
poke64(a + EDI_PRICAT_DESCLEN, 20);
poke64(a + EDI_PRICAT_GROSSPRICE, 1999);
poke64(a + EDI_PRICAT_NETPRICE, 1799);
poke64(a + EDI_PRICAT_CURRENCY, "EUR"c as int64);
poke64(a + EDI_PRICAT_CURRENCYLEN, 3);
poke64(a + EDI_PRICAT_VALIDFROM, "20260901"c as int64);
poke64(a + EDI_PRICAT_VALIDTO, "20261231"c as int64);
var b: int64 := items + EDI_PRICAT_ITEM_SIZE;
poke64(b + EDI_PRICAT_GTIN, "04012345678918"c as int64);
poke64(b + EDI_PRICAT_GTINLEN, 14);
poke64(b + EDI_PRICAT_DESC, "Espressobohnen 1kg"c as int64);
poke64(b + EDI_PRICAT_DESCLEN, 18);
poke64(b + EDI_PRICAT_GROSSPRICE, 4950);
poke64(b + EDI_PRICAT_NETPRICE, 4450);
poke64(b + EDI_PRICAT_CURRENCY, "EUR"c as int64);
poke64(b + EDI_PRICAT_CURRENCYLEN, 3);
// GTIN vor dem Schreiben selbst pruefen - PRICAT tut es nicht
if (EdiGtinCheck(peek64(a + EDI_PRICAT_GTIN) as pchar, 14) != 1) { PrintLn("GTIN ungueltig"); return 1; }
var out: int64 := alloc(4096);
var n: int64 := EdiPricatWrite(items, 2, out, 4096);
PrintLn(Feld(out, n));
var it2: int64 := alloc(8 * EDI_PRICAT_ITEM_SIZE);
var cnt: int64 := EdiPricatRead(out, n, it2, 8);
PrintLn(StrConcat("Artikel: ", IntToStr(cnt)));
i := 0;
while (i < cnt) {
var it: int64 := it2 + i * EDI_PRICAT_ITEM_SIZE;
PrintLn(StrConcat(StrConcat(" ", Feld(peek64(it + EDI_PRICAT_GTIN), peek64(it + EDI_PRICAT_GTINLEN))),
StrConcat(" netto/100: ", IntToStr(peek64(it + EDI_PRICAT_NETPRICE)))));
i += 1;
}
// PARTIN: Stammdaten eines Partners
var party: int64 := alloc(EDI_PARTY_SIZE);
i := 0;
while (i < EDI_PARTY_SIZE) { poke8(party + i, 0); i := i + 1; }
poke64(party + EDI_PARTY_GLN, "4012345000009"c as int64);
poke64(party + EDI_PARTY_GLNLEN, 13);
poke64(party + EDI_PARTY_NAME, "Muster Handel GmbH"c as int64);
poke64(party + EDI_PARTY_NAMELEN, 18);
poke64(party + EDI_PARTY_STREET, "Hafenstrasse 12"c as int64);
poke64(party + EDI_PARTY_STREETL, 15);
poke64(party + EDI_PARTY_CITY, "Hamburg"c as int64);
poke64(party + EDI_PARTY_CITYL, 7);
poke64(party + EDI_PARTY_POSTCODE, "20457"c as int64);
poke64(party + EDI_PARTY_POSTCODEL, 5);
poke64(party + EDI_PARTY_COUNTRY, "DE"c as int64);
poke64(party + EDI_PARTY_COUNTRYL, 2);
poke64(party + EDI_PARTY_ROLE, "BY"c as int64);
poke64(party + EDI_PARTY_ROLEL, 2);
n := EdiPartinWrite(party, out, 4096);
PrintLn(Feld(out, n));
return 0;
}
BGM+9+PRICAT+9'LIN+1++04012345678901:SRV'IMD+F++:::Kaffee gemahlen 500g'PRI+AAB:19.99:CP'PRI+AAA:17.99:CP'DTM+194:20260901:102'DTM+206:20261231:102'LIN+2++04012345678918:SRV'IMD+F++:::Espressobohnen 1kg'PRI+AAB:49.50:CP'PRI+AAA:44.50:CP'CNT+2:2'
Artikel: 2
04012345678901 netto/100: 1799
04012345678918 netto/100: 4450
BGM+349++9'NAD+BY+4012345000009::9+Muster Handel GmbH+Hafenstrasse 12+Hamburg+20457+DE'
PRI+AAB trägt den Brutto-, PRI+AAA den Nettopreis; DTM+194/DTM+206 sind Beginn und Ende der Preisgültigkeit. Fehlt ein Gültigkeitsdatum, entfällt das jeweilige DTM-Segment (siehe zweiter Artikel).
std.edi.corestd.alloc| Offset-Konstante | Inhalt |
|---|---|
EDI_PRICAT_GTIN / EDI_PRICAT_GTINLEN | GTIN-Zeiger und -Länge |
EDI_PRICAT_DESC / EDI_PRICAT_DESCLEN | Artikelbeschreibung |
EDI_PRICAT_GROSSPRICE | Bruttopreis × 100 (z. B. 299 = 2,99 €) |
EDI_PRICAT_NETPRICE | Nettopreis × 100 |
EDI_PRICAT_CURRENCY / EDI_PRICAT_CURRENCYLEN | Währungscode (z. B. „EUR“) |
EDI_PRICAT_UNIT / EDI_PRICAT_UNITLEN | Mengeneinheit (z. B. „PCE“, optional) |
EDI_PRICAT_VALIDFROM | Zeiger auf Gültigkeitsbeginn „YYYYMMDD“ (0 = keins) |
EDI_PRICAT_VALIDTO | Zeiger auf Gültigkeitsende „YYYYMMDD“ (0 = keins) |
| Offset-Konstante | Inhalt |
|---|---|
EDI_PARTY_GLN / EDI_PARTY_GLNLEN | GLN-Zeiger und -Länge |
EDI_PARTY_NAME / EDI_PARTY_NAMELEN | Firmenname |
EDI_PARTY_STREET / EDI_PARTY_STREETL | Straße + Hausnummer |
EDI_PARTY_CITY / EDI_PARTY_CITYL | Ort |
EDI_PARTY_POSTCODE / EDI_PARTY_POSTCODEL | Postleitzahl |
EDI_PARTY_COUNTRY / EDI_PARTY_COUNTRYL | Ländercode (z. B. „DE“) |
EDI_PARTY_ROLE / EDI_PARTY_ROLEL | Parteirolle (z. B. „SU“, „BY“) |
Aktivitätsdaten (PROACT) für Warengruppen-Berichte.
| Offset-Konstante | Inhalt |
|---|---|
EDI_PROACT_GTIN / EDI_PROACT_GTINLEN | GTIN-Zeiger und -Länge |
EDI_PROACT_QTY | Menge × 1000 (3 Dezimalstellen) |
EDI_PROACT_DATE | Zeiger auf Datum „YYYYMMDD“ |
EDI_PROACT_TYPE | Aktivitätstyp: 1=Verkauf, 2=Rückgabe, 3=Transfer |
| Signatur | Beschreibung |
|---|---|
EdiGtinCheck(ptr: pchar, len: int64): int64 | Prüft GTIN-Prüfziffer (Mod-10). Gibt 1=gültig, 0=ungültig. Unterstützt Längen 8, 12, 13, 14. |
EdiGlnCheck(ptr: int64, len: int64): int64 | Prüft GLN-Prüfziffer (Mod-10). Gibt 1=gültig, 0=ungültig. Erwartet exakt 13 Stellen. |
| Signatur | Beschreibung |
|---|---|
EdiPricatWrite(items: int64, count: int64, out: int64, outMax: int64): int64 | Schreibt PRICAT. GTINs werden nicht validiert (Caller-Verantwortung). |
EdiPricatRead(buf: int64, bufLen: int64, items: int64, maxItems: int64): int64 | Parst PRICAT; gibt Artikelanzahl zurück. Zero-Copy: Zeiger in items zeigen in buf. |
| Signatur | Beschreibung |
|---|---|
EdiPartinWrite(party: int64, out: int64, outMax: int64): int64 | Schreibt PARTIN (eine Partei) |
EdiPartinRead(buf: int64, bufLen: int64, party: int64): int64 | Parst PARTIN; gibt EDI_OK oder Fehlercode |
import std.edi.catalog;
import std.alloc;
import std.string;
fn main(): int64 {
// Zweite GTIN traegt absichtlich eine falsche Pruefziffer
var msg: pchar := "BGM+9+PRICAT+9'LIN+1++04012345678901:SRV'PRI+AAA:17.99:CP'LIN+2++04012345678911:SRV'PRI+AAA:44.50:CP'CNT+2:2'"c;
var items: int64 := alloc(64 * EDI_PRICAT_ITEM_SIZE);
var count: int64 := EdiPricatRead(msg as int64, StrLen(msg), items, 64);
PrintLn(StrConcat("Positionen: ", IntToStr(count)));
var i: int64 := 0;
while (i < count) {
var item: int64 := items + i * EDI_PRICAT_ITEM_SIZE;
var gptr: int64 := peek64(item + EDI_PRICAT_GTIN);
var glen: int64 := peek64(item + EDI_PRICAT_GTINLEN);
if (EdiGtinCheck(gptr as pchar, glen) == 0) {
PrintLn(StrConcat("Ungueltige GTIN in Position ", IntToStr(i + 1)));
}
i := i + 1;
}
free(items, 64 * EDI_PRICAT_ITEM_SIZE);
return 0;
}
Positionen: 2
Ungueltige GTIN in Position 2
EdiPricatWrite noch EdiPartinWrite prüfen GTIN oder GLN. Wer sich auf saubere Stammdaten verlässt, ruft EdiGtinCheck/EdiGlnCheck selbst auf — beim Erzeugen wie beim Einlesen.1799 bedeutet 17,99 €. EDI_PRICAT_GROSSPRICE ist der Listen-, EDI_PRICAT_NETPRICE der Nettopreis.YYYYMMDD (8 Zeichen, ohne Längenfeld) oder 0.EdiPartinWrite erzeugt BGM+349 und ein NAD-Segment mit der Rolle aus EDI_PARTY_ROLE (BY Käufer, SU Lieferant, DP Lieferstelle, IV Rechnungsempfänger).EdiPricatWrite liest jedes Feld, auch die optionalen.| Unit | Datei |
|---|---|
std.edi.catalog | std/edi/catalog.lyx |
Letzte Aktualisierung: 2026-08-13 — beide Beispiele lauffähig gemacht und ausgeführt (lyxc 1.0.17K), PARTIN-Beispiel und Hinweisabschnitt ergänzt
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).