# Datanorm Format Dokumentation

## Allgemeines

Datanorm ist ein Dateiformat für den Datenaustausch von Artikelstammdaten zwischen Produktlieferant, Fachgroßhandel und Handwerksbetrieb. Es wird vornehmlich im Baunebengewerbe (Sanitär, Heizung, Elektro, Maler) verwendet.

**Wichtig:** Datanorm ist kein offener Standard. Die offizielle Spezifikation ist kostenpflichtig über den Krammer Verlag erhältlich.

## Datanorm Versionen

- **Datanorm 3.0**: Feste Feldbreiten (128 Zeichen pro Satz), ASCII
- **Datanorm 4.0**: Semikolon-getrennte Felder, erweiterte Funktionen
- **Datanorm 5.0**: XML-basiert

## Dateistruktur

Eine Datanorm-Lieferung besteht aus mehreren Dateien:

| Datei | Inhalt |
|-------|--------|
| `DATANORM.001` - `.999` | Artikelstammdaten (A/B-Sätze) |
| `DATPREIS.001` - `.999` | Preisdaten (P-Sätze) |
| `DATANORM.WRG` | Warengruppen |
| `DATANORM.RAB` | Rabattgruppen |

## Satzarten

| Kennzeichen | Typ | Beschreibung |
|-------------|-----|--------------|
| A | Artikelsatz | Stammdaten des Artikels |
| B | Ergänzungssatz | Zusatzinfos, EAN, VPE, Langtext |
| P | Preissatz | Preisinformationen |
| T | Textsatz | Mehrzeilige Texte |
| G | Grafiksatz | Bildverknüpfungen |

## A-Satz (Artikelstammdaten) - Datanorm 4.0 Semikolon-Format

### Sonepar-Format

```
A;N;ArtNr;TextKz;Kurztext1;Kurztext2;PreisKz;PE;ME;Preis;RabGrp;WG;LangTextKey
```

| Index | Feld | Beschreibung | Beispiel |
|-------|------|--------------|----------|
| 0 | Satzart | Immer "A" | `A` |
| 1 | **Aktionscode** | **N=Neu, A=Ändern, L=Löschen** | `N` |
| 2 | Artikelnummer | Eindeutige Nummer | `0480145` |
| 3 | Textkennzeichen | Text-Typ | `00` |
| 4 | Kurztext 1 | Erste Bezeichnung (max 40 Z.) | `OBO BETT. Verschraubung` |
| 5 | Kurztext 2 | Zweite Bezeichnung (max 40 Z.) | `V-TEC PG21 LGR` |
| 6 | Preiskennzeichen | 1=Brutto, 2=Netto | `1` |
| 7 | **PE (Preiseinheit)** | **CODE** (siehe unten) | `2` |
| 8 | ME (Mengeneinheit) | Einheit | `Stck` |
| 9 | Preis | In Cent (wenn vorhanden) | `59085` |
| 10 | Rabattgruppe | Rabatt-Code | `A12N` |
| 11 | Warengruppe | Waren-Code | `303` |
| 12 | Langtextschlüssel | Verknüpfung zu Texten | ` ` |

### Preiseinheit-Codes (PE) - WICHTIG!

**Die Preiseinheit ist ein CODE, nicht die tatsächliche Menge!**

| Code | Bedeutung | Divisor |
|------|-----------|---------|
| 0 (oder leer) | Preis pro 1 Stück | 1 |
| 1 | Preis pro 10 Stück | 10 |
| 2 | Preis pro 100 Stück | 100 |
| 3 | Preis pro 1000 Stück | 1000 |

**Beispiel:**
```
A;N;0480145;00;OBO BETT. Verschraubung;V-TEC PG21 LGR;1;2;Stck;...
                                                       ↑
                                                       PE-Code 2 = pro 100 Stück
```

Wenn DATPREIS den Preis 9997 (= 99,97 €) liefert:
- Stückpreis = 99,97 € / 100 = **0,9997 €**

### Aktionscode - Artikelstatus

Der Aktionscode gibt an, ob ein Artikel neu ist, geändert wurde oder nicht mehr verfügbar ist:

| Code | Bedeutung | Verhalten |
|------|-----------|-----------|
| N | Neu | Artikel wird angelegt |
| A | Ändern | Artikel wird aktualisiert |
| L | Löschen | Artikel wird als inaktiv markiert (`active=0`) |

**Wichtig:** Bei `L`-Artikeln wird das Feld `active` auf `0` gesetzt. Diese Artikel erscheinen nicht mehr in Suchergebnissen und können beim Massenupdate als "nicht mehr verfügbar" gekennzeichnet werden.

## B-Satz (Ergänzungssatz) - Sonepar-Format

```
B;N;ArtNr;Matchcode; ; ;;;;EAN; ; ;0;VPE;;;
```

| Index | Feld | Beschreibung |
|-------|------|--------------|
| 0 | Satzart | `B` |
| 1 | Aktion | N/L/A |
| 2 | Artikelnummer | Bezug zum A-Satz |
| 3 | Matchcode | Suchbegriff |
| 8 | EAN | 13-stellige EAN/GTIN |
| 13 | VPE | Verpackungseinheit (tatsächliche Menge) |

**Hinweis:** Die VPE im B-Satz ist die Verpackungseinheit (z.B. 100 Stück pro Packung), während der PE-Code im A-Satz die Preisbasis definiert. Diese können unterschiedlich sein!

## P-Satz (Preissatz) - DATPREIS-Datei

### Format: Mehrere Artikel pro Zeile

```
P;A;ArtNr1;PreisKz1;Preis1;x;Zuschlag1;x;x;x;ArtNr2;PreisKz2;Preis2;x;Zuschlag2;...
```

| Index | Feld | Beschreibung |
|-------|------|--------------|
| 0 | P | Satzkennung |
| 1 | A | Aktionskennung |
| 2 | ArtNr | Artikelnummer |
| 3 | PreisKz | Preiskennzeichen (2=Nettopreis) |
| 4 | Preis | Materialpreis in **Cent** (für A-Satz PE-Einheit!) |
| 5 | x | Unbekannt (immer 1 bei Sonepar) |
| 6 | Zuschlag | **Metallzuschlag** in Cent (Kupfer/Aluminium) |
| 7-10 | x | Weitere Felder (Flags) |

**Wichtig:** Der Preis in DATPREIS ist bereits für die PE-Einheit aus dem A-Satz angegeben! Keine Normalisierung nötig.

### Metallzuschlag (für Kabel)

Bei Kabeln und metallhaltigen Produkten gibt es oft zwei Preiskomponenten:
- **Materialpreis** (Preis): Grundpreis des Produkts
- **Metallzuschlag** (Zuschlag): Zusatzkosten für Kupfer/Aluminium

**Gesamtpreis = Materialpreis + Metallzuschlag**

**Beispiel Kabel NYM-J 5x1,5:**
```
P;A;0110350;2;2920;2;7629;0;1;0;...
```
- Materialpreis: 2920 Cent = 29,20 €/100m
- Metallzuschlag: 7629 Cent = 76,29 €/100m
- **Gesamtpreis: 105,49 €/100m = 1,05 €/m**

**Beispiel ohne Metallzuschlag:**
```
P;A;0480145;2;9997;1;0;1;0;1;0;0480146;2;20689;1;0;1;0;1;0;
```
- Artikel 0480145: Preis = 9997 Cent = 99,97 €

## Preisberechnung

### Formel für Stückpreis

```
Stückpreis = Preis / PE_Divisor
```

Wobei PE_Divisor aus dem PE-Code berechnet wird:
- Code 0 → Divisor 1
- Code 1 → Divisor 10
- Code 2 → Divisor 100
- Code 3 → Divisor 1000

### Beispiel

```
Artikel: 0480145
DATPREIS: 9997 (Cent) = 99,97 €
A-Satz PE-Code: 2 → Divisor 100

Stückpreis = 99,97 € / 100 = 0,9997 €
```

## Datenbankfelder

| Feld | Typ | Beschreibung |
|------|-----|--------------|
| `price` | DOUBLE | Materialpreis aus DATPREIS (in Euro) |
| `price_unit` | INT | Konvertierter PE-Divisor (1, 10, 100, 1000) |
| `price_unit_code` | TINYINT | Originaler PE-Code (0, 1, 2, 3) |
| `price_type` | TINYINT | Preiskennzeichen (1=Brutto, 2=Netto) |
| `metal_surcharge` | DOUBLE | Metallzuschlag (Kupfer/Aluminium) in Euro |
| `vpe` | INT | VPE aus B-Satz (Verpackungseinheit) |
| `action_code` | CHAR(1) | Aktionscode (N=Neu, A=Ändern, L=Löschen) |
| `active` | TINYINT | Artikelstatus (1=aktiv, 0=gelöscht bei L) |

### Preisberechnung mit Metallzuschlag

```
Gesamtpreis = price + metal_surcharge
Stückpreis = Gesamtpreis / price_unit
```

**Beispiel:**
```
price = 29.20 €
metal_surcharge = 76.29 €
price_unit = 100

Gesamtpreis = 29.20 + 76.29 = 105.49 €
Stückpreis = 105.49 / 100 = 1.0549 €
```

## Quellen

- [Datanorm Wikipedia](https://de.wikipedia.org/wiki/Datanorm)
- [DATANORM.de](https://www.datanorm.de/)
- [Comtech Hilfe](https://hilfe.comtech.at/ce/773/html/datanorm_datei.htm)

## Hinweis

Diese Dokumentation basiert auf der Analyse von Sonepar-Datanorm-Dateien und öffentlich verfügbaren Informationen. Für die vollständige offizielle Spezifikation wird das Datanorm-Taschenbuch vom Krammer Verlag empfohlen.
