std.edi.rfq

Anfrage- und Angebotsprozess per EDIFACT: Käufer sendet eine Angebotsanfrage (REQOTE), Lieferant antwortet mit einem Angebot (QUOTES). Der Kreuzreferenz-Mechanismus über RFF+RFQ ist Pflicht — jedes QUOTES muss die Nummer des zugehörigen REQOTE tragen.

  • REQOTE (BGM 311) — Request for Quotation: Artikel, Mengen, Wunsch-Liefertermine
  • QUOTES (BGM 315) — Quotation: Preise, Verfügbarkeit, Liefertermine

import std.edi.rfq;
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 {
    // 1. Anfrage (REQOTE) ueber zwei Artikel
    var rl: int64 := alloc(2 * EDI_RFQ_LINE_SIZE);
    var i: int64 := 0;
    while (i < 2 * EDI_RFQ_LINE_SIZE) { poke8(rl + i, 0); i := i + 1; }
    poke64(rl + EDI_RFQ_LINE_GTIN,    "04012345678901"c as int64);
    poke64(rl + EDI_RFQ_LINE_GTINLEN, 14);
    poke64(rl + EDI_RFQ_LINE_QTY,     240);
    poke64(rl + EDI_RFQ_LINE_DATE,    "20260915"c as int64);
    var r1: int64 := rl + EDI_RFQ_LINE_SIZE;
    poke64(r1 + EDI_RFQ_LINE_GTIN,    "04012345678918"c as int64);
    poke64(r1 + EDI_RFQ_LINE_GTINLEN, 14);
    poke64(r1 + EDI_RFQ_LINE_QTY,     60);

    var out: int64 := alloc(4096);
    var n: int64 := EdiReqoteWrite("ANF-2026-0007"c, "20260813"c, rl, 2, out, 4096);
    PrintLn(Feld(out, n));

    var hdr: int64 := alloc(EDI_RFQHDR_SIZE);
    var lin: int64 := alloc(8 * EDI_RFQ_LINE_SIZE);
    var cnt: int64 := EdiReqoteRead(out, n, hdr, lin, 8);
    PrintLn(StrConcat(StrConcat("Anfrage ", Feld(peek64(hdr + EDI_RFQHDR_NUM), peek64(hdr + EDI_RFQHDR_NUMLEN))),
            StrConcat(" mit Positionen: ", IntToStr(cnt))));

    // 2. Angebot (QUOTES) - Position 2 nicht lieferbar
    var ql: int64 := alloc(2 * EDI_QUOTE_LINE_SIZE);
    i := 0;
    while (i < 2 * EDI_QUOTE_LINE_SIZE) { poke8(ql + i, 0); i := i + 1; }
    poke64(ql + EDI_QUOTE_LINE_GTIN,        "04012345678901"c as int64);
    poke64(ql + EDI_QUOTE_LINE_GTINLEN,     14);
    poke64(ql + EDI_QUOTE_LINE_PRICE,       1899);
    poke64(ql + EDI_QUOTE_LINE_CURRENCY,    "EUR"c as int64);
    poke64(ql + EDI_QUOTE_LINE_CURRENCYLEN, 3);
    poke64(ql + EDI_QUOTE_LINE_DATE,        "20260920"c as int64);
    poke64(ql + EDI_QUOTE_LINE_AVAIL,       1);
    var q1: int64 := ql + EDI_QUOTE_LINE_SIZE;
    poke64(q1 + EDI_QUOTE_LINE_GTIN,        "04012345678918"c as int64);
    poke64(q1 + EDI_QUOTE_LINE_GTINLEN,     14);
    poke64(q1 + EDI_QUOTE_LINE_AVAIL,       0);

    n := EdiQuotesWrite("ANF-2026-0007"c, "ANG-5501"c, ql, 2, out, 4096);
    PrintLn(Feld(out, n));

    var qhdr: int64 := alloc(EDI_QUOTEHDR_SIZE);
    var qlin: int64 := alloc(8 * EDI_QUOTE_LINE_SIZE);
    cnt := EdiQuotesRead(out, n, qhdr, qlin, 8);
    i := 0;
    while (i < cnt) {
        var q: int64 := qlin + i * EDI_QUOTE_LINE_SIZE;
        if (peek64(q + EDI_QUOTE_LINE_AVAIL) == 1) {
            PrintLn(StrConcat(StrConcat("lieferbar:  ", Feld(peek64(q + EDI_QUOTE_LINE_GTIN), peek64(q + EDI_QUOTE_LINE_GTINLEN))),
                    StrConcat(" zu Preis/100 ", IntToStr(peek64(q + EDI_QUOTE_LINE_PRICE)))));
        } else {
            PrintLn(StrConcat("nicht lieferbar: ", Feld(peek64(q + EDI_QUOTE_LINE_GTIN), peek64(q + EDI_QUOTE_LINE_GTINLEN))));
        }
        i += 1;
    }
    return 0;
}

BGM+311+ANF-2026-0007+9'DTM+137:20260813:102'LIN+1++04012345678901:SRV'QTY+21:240'DTM+10:20260915:102'LIN+2++04012345678918:SRV'QTY+21:60'CNT+2:2'
Anfrage ANF-2026-0007 mit Positionen: 2
BGM+315+ANG-5501+9'RFF+RFQ:ANF-2026-0007'LIN+1++04012345678901:SRV'PRI+AAA:18.99:CP'LOC+11:1'DTM+2:20260920:102'LIN+2++04012345678918:SRV'LOC+11:0'CNT+2:2'
lieferbar:  04012345678901 zu Preis/100 1899
nicht lieferbar: 04012345678918

Die Verfügbarkeit steckt im LOC+11-Segment (1 = lieferbar, 0 = nicht lieferbar); RFF+RFQ verweist auf die ursprüngliche Anfrage. Eine nicht lieferbare Position trägt weder Preis noch Liefertermin.


Imports

  • std.edi.core
  • std.alloc

Structs

EdiRfqLine (EDI_RFQ_LINE_SIZE = 48 Bytes)

Eine Position in einer Angebotsanfrage.

Offset-Konstante Inhalt
EDI_RFQ_LINE_GTIN / EDI_RFQ_LINE_GTINLEN GTIN-Zeiger und -Länge
EDI_RFQ_LINE_QTY Angefragte Menge
EDI_RFQ_LINE_UNIT / EDI_RFQ_LINE_UNITLEN Mengeneinheit (z. B. „PCE“, optional)
EDI_RFQ_LINE_DATE Zeiger auf 8-stelliges Wunschdatum „YYYYMMDD“ (0 = keins)

EdiQuoteLine (EDI_QUOTE_LINE_SIZE = 56 Bytes)

Eine Position in einem Angebot.

Offset-Konstante Inhalt
EDI_QUOTE_LINE_GTIN / EDI_QUOTE_LINE_GTINLEN GTIN-Zeiger und -Länge
EDI_QUOTE_LINE_PRICE Preis × 100 (Festkomma; 1999 = 19,99 €)
EDI_QUOTE_LINE_CURRENCY / EDI_QUOTE_LINE_CURRENCYLEN Währung (z. B. „EUR“)
EDI_QUOTE_LINE_DATE Zeiger auf Lieferdatum „YYYYMMDD“ (0 = keins)
EDI_QUOTE_LINE_AVAIL Verfügbarkeit: 1 = verfügbar, 0 = nicht verfügbar

EdiRfqHdr (EDI_RFQHDR_SIZE = 32 Bytes)

Kopfdaten eines eingehenden REQOTE.

Offset-Konstante Inhalt
EDI_RFQHDR_NUM / EDI_RFQHDR_NUMLEN RFQ-Nummer (Zeiger in Empfangspuffer)
EDI_RFQHDR_DATE / EDI_RFQHDR_DATELEN Dokumentdatum

EdiQuoteHdr (EDI_QUOTEHDR_SIZE = 32 Bytes)

Kopfdaten eines eingehenden QUOTES.

Offset-Konstante Inhalt
EDI_QUOTEHDR_NUM / EDI_QUOTEHDR_NUMLEN Angebotsnummer
EDI_QUOTEHDR_RFQREF / EDI_QUOTEHDR_RFQREFLEN Rückverweis auf REQOTE-Nummer (RFF+RFQ)

Funktionen

REQOTE

Signatur Beschreibung
EdiReqoteWrite(rfqNum: int64, date: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 Schreibt REQOTE. rfqNum ist Pflicht (0 → gibt -1 zurück). date = Zeiger auf „YYYYMMDD“ oder 0.
EdiReqoteRead(buf: int64, bufLen: int64, hdr: int64, lines: int64, maxLines: int64): int64 Parst REQOTE; befüllt hdr (EDI_RFQHDR_SIZE) und lines-Array. Gibt Zeilenanzahl zurück. Zero-Copy: Zeiger in hdr/lines zeigen in buf.

QUOTES

Signatur Beschreibung
EdiQuotesWrite(rfqRef: int64, quoteNum: int64, lines: int64, lineCount: int64, out: int64, outMax: int64): int64 Schreibt QUOTES. rfqRef ist Pflicht (0 → gibt -1 zurück). quoteNum = eigene Angebotsnummer (optional, 0 erlaubt).
EdiQuotesRead(buf: int64, bufLen: int64, hdr: int64, lines: int64, maxLines: int64): int64 Parst QUOTES; befüllt hdr und lines. Gibt Zeilenanzahl zurück.

Hinweise

  • rfqRef Pflicht in QUOTES: EdiQuotesWrite gibt -1 zurück, wenn rfqRef null oder leer ist. EDIFACT fordert diesen Rückverweis (RFF+RFQ) für die Auftragszuordnung.
  • Preise als Festkomma: Preise werden als int64 × 100 gespeichert. 1999 bedeutet 19,99. Beim Schreiben wird daraus 19.99 im EDIFACT-Format.
  • Datum-Format: Alle Datum-Felder erwarten genau 8 Zeichen YYYYMMDD — keine Trennzeichen, kein Längenfeld; 0 lässt das DTM-Segment weg.
  • Verfügbarkeit ist Pflichtangabe: EDI_QUOTE_LINE_AVAIL wird immer als LOC+11 geschrieben. Bei 0 (nicht lieferbar) unterdrückt EdiQuotesWrite Preis und Liefertermin — ein gesetzter Preis geht dann verloren.
  • Zwei getrennte Zeilen-Structs: Anfrage (EDI_RFQ_LINE_*, 48 Bytes) und Angebot (EDI_QUOTE_LINE_*, 56 Bytes) haben unterschiedliche Layouts; die Antwort ist keine Kopie der Anfrage.
  • Structs vor dem Befüllen nullen.

Quelldatei

Unit Datei
std.edi.rfq std/edi/rfq.lyx

Letzte Aktualisierung: 2026-08-13 — Beispiel deckt jetzt den kompletten Ablauf Anfrage → Angebot ab, ist lauffähig und ausgeführt (lyxc 1.0.17K); Verhalten bei nicht lieferbaren Positionen 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).