goBnn/bnn.go

267 lines
12 KiB
Go
Executable File

package bnn
import (
"bufio"
"io"
"os"
"strconv"
"strings"
"golang.org/x/text/encoding/charmap"
)
// Info Structure of headline
type Info struct {
Kennung string //BNN als Kennung des Dateityps
Version int //3 als Versionsnummer der Schnittstelle
Zeichensatz int //0=AscII 1=Ansi
Versenderadresse string //Name, Ort ... des Händlers
Umfang string //V=vollständige Preisliste, T=Teilliste, S=Sonderliste
Inhalt string //Text, der die Preisliste näher beschreibt
Preiswaehrung string //Währung banküblich (DEM=DM, ATS=österr.Schilling, EUR=Euro)
DatumAb string //Preise gültig ab JJJJMMTT
DatumBis string //gültig bis, 0=unbestimmt
Abgabedatum string //Datum der Datei-Erstellung JJJJMMTT
Abgabezeit string //Uhrzeit der Datei-Erstellung SSMM
Dateizaehler int //Angabe der Dateinummer, Datei/Diskette1
}
// Item Structure of each Item
type Item struct {
ArtikelNr string //hausinterne Artikelnummer, mit der bestellt werden soll
Aenderungskennung string //N=neu, A=Änderung, X=ausgelistet, R=Restbestand, V=vorübergehend ausgelistet, W=wiedergelistet
AenderungsDatum int //letztes Artikel-Änderungsdatum JJJJMMTT
AenderungsZeit int //Uhrzeit letzte Artikel-Änderung SSMM
EANladen int //EAN-Nummer Ladeneinheit (1)
EANbestell int //EAN-Nummer Bestelleinheit (1)
Bezeichnung string //Artikelbezeichnung
Bezeichnung2 string //Zusatz-Artikelbezeichnung
Bezeichnung3 string //Bezeichnung für Etiketten- bzw. Kassentext
Handelsklasse string //Handelsklasse (in römischen Zahlen: I, II, III, IV ...)
HerstellerInverkehrbringer string //Herstellerkürzel (nach BNN-Liste) des Herstellers lt. Deklaration auf der Verpackung
Hersteller string //Herstellerkürzel (nach BNN-Liste) falls abweichend von der Verpackung
Herkunft string //Qualitätsland (Auto-Länderkennzeichen)
Qualitaet string //Qualitätskennung (nach BNN-IK-Liste)
Kontrollstelle string //EG-Kontrollstellen-Kennung
MHDRestlaufzeit int //übliche Restlaufzeit in Tagen
WGBNN int //Warengruppe BNNEH (nach BNN-Liste)
WGIfH int //Warengruppe Institut für Handelsforschung (Liste beim BNN erhältlich)
WGGH int //Warengruppe des jeweiligen Großhändlers
ErsatzArtikelNr string //Ersatz-Artikelnummer Ersatzartikel wird geliefert, falls sonst nicht lieferbar
MinBestellMenge float64 //Mindestbestellmenge in Bestelleinheit (1)
Bestelleinheit string //Bestelleinheit (1) = Verkaufseinheit des Lieferanten
BestelleinheitsMenge float64 //Anzahl Ladeneinheiten je Bestelleinheit (1)
Ladeneinheit string //Ladeneinheit (1) = Verkaufseinheit im Laden
Mengenfaktor float64 //Faktor zur Menge-Preis-Relation Ladeneinheit (2)
Gewichtsartikel bool //J=Ja, N=Nein Ja, wenn der Artikel nur abgewogen verkauft wird
PfandNrLadeneinheit string //hausinterne PfandNr für Ladeneinheit (1)
PfandNrBestelleinheit string //hausinterne PfandNr für Bestelleinheit (1)
GewichtLadeneinheit float64 //Bruttogewicht einer Ladeneinheit (1) in kg
GewichtBestelleinheit float64 //Bruttogewicht einer Bestelleinheit (1) in kg
Breite int //Packungsbreite der Ladeneinheit in cm
Hoehe int //Packungshöhe der Ladeneinheit in cm
Tiefe int //Packungstiefe der Ladeneinheit in cm
MwstKennung int //Mehrwertsteuer 1=reduziert 2=voll 3=LandwirtsSatz
VkFestpreis float64 //Festpreis Endkunde incl. MWSt. lt. Hersteller (Bücher)
EmpfVk float64 //empf.VK des Herstellers incl. MWSt. je Ladeneinheit
EmpfVkGH float64 //VK-Vorschlag des Lieferanten incl. MWSt. je Ladeneinheit
Preis float64 //Einzelpreis o. MWSt je Ladeneinheit Mengenfaktor beachten!
rabattfaehig bool //J=Ja, N=Nein
skontierfaehig bool //J=Ja, N=Nein
StaffelMenge1 float64 //Staffelmenge in Ladeneinheit (1)
StaffelPreis1 float64 //Staffelpreis je Ladeneinheit (1) o. MWSt.
rabattfaehig1 bool //J=Ja, N=Nein
skontierfaehig1 bool //J=Ja, N=Nein
StaffelMenge2 float64 //Staffelmenge in Ladeneinheit (1)
StaffelPreis2 float64 //Staffelpreis je Ladeneinheit (1) o. MWSt.
rabattfaehig2 bool //J=Ja, N=Nein
skontierfaehig2 bool //J=Ja, N=Nein
StaffelMenge3 float64 //Staffelmenge in Ladeneinheit (1)
StaffelPreis3 float64 //Staffelpreis je Ladeneinheit (1) o. MWSt.
rabattfaehig3 bool //J=Ja, N=Nein
skontierfaehig3 bool //J=Ja, N=Nein
StaffelMenge4 float64 //Staffelmenge in Ladeneinheit (1)
StaffelPreis4 float64 //Staffelpreis je Ladeneinheit (1) o. MWSt.
rabattfaehig4 bool //J=Ja, N=Nein
skontierfaehig4 bool //J=Ja, N=Nein
StaffelMenge5 float64 //Staffelmenge in Ladeneinheit (1)
StaffelPreis5 float64 //Staffelpreis je Ladeneinheit (1) o. MWSt.
rabattfaehig5 bool //J=Ja, N=Nein
skontierfaehig5 bool //J=Ja, N=Nein
Artikelart string //F=Frische (mit Tagespreisen), T=Trocken, W=NaturWaren, P=Pfand (dieser Artikel ist das Pfand selbst!), A=Artikel aus FrischePreisliste (aktuelles Angebot)
Aktionspreis string //A=Aktionspreis
AktionspreisGueltigAb string //Datum JJJJMMTT, 0 bzw. leer = ab sofort
AktionspreisGueltigBis string //Datum JJJJMMTT, 0 bzw. leer = unbestimmt
empfVkAktion float64 //Aktions-VK-Vorschlag incl. MWSt.
GrundpreisEinheit string //Einheit der Grundpreisauszeichnung (kg, l)
GrundpreisFaktor float64 //Mengen-Faktor der Grundpreiseinheit zur Ladeneinheit
LieferbarAb string //Datum JJJJMMTT
LieferbarBis string //Datum JJJJMMTT
}
// Bnn Information of file
type Bnn struct {
Info Info
Items []Item
}
func convertBnnBool(s string) bool {
if s == "J" {
return true
}
return false
}
func convertStringToInt(s string) int {
ret, _ := strconv.Atoi(s)
return ret
}
func convertStringToFloat(s string) float64 {
ret, _ := strconv.ParseFloat(strings.ReplaceAll(s, ",", "."), 64)
return ret
}
// ReadBnnFile Reads file and returns object with all containing information
func ReadBnnFile(path string) (Bnn, error) {
file, err := os.Open(path)
if err != nil {
return Bnn{}, err
}
defer file.Close()
content, err := ReadBnn(file)
if err != nil {
return Bnn{}, err
}
return content, nil
}
// ReadBnn Reads from reader and returns object with all containing information
func ReadBnn(r io.Reader) (Bnn, error) {
//dr := charmap.CodePage850.NewDecoder().Reader(r)
scanner := bufio.NewScanner(r)
var lines []string
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
var content Bnn
var encoding string
for i, line := range lines {
var item Item
// How to decode file? Use header info for encoding information.
if i == 0 && strings.Split(line, ";")[2] == "0" {
encoding = "ascii"
}
// Example file for ASCII was provided by Paxan
// Extended ASCII has been used -> ä 132 \u0084
if encoding == "ascii" {
line, _ = charmap.CodePage850.NewDecoder().String(line)
}
col := strings.Split(line, ";")
// Headline contains infos
if i == 0 {
content.Info.Kennung = col[0]
content.Info.Version = convertStringToInt(col[1])
content.Info.Zeichensatz = convertStringToInt(col[2])
content.Info.Versenderadresse = col[3]
content.Info.Umfang = col[4]
content.Info.Inhalt = col[5]
content.Info.Preiswaehrung = col[6]
content.Info.DatumAb = col[7]
content.Info.DatumBis = col[8]
content.Info.Abgabedatum = col[9]
content.Info.Abgabezeit = col[10]
content.Info.Dateizaehler = convertStringToInt(col[11])
continue
}
// Jump over last line and exit
if len(col) == 3 {
break
}
item.ArtikelNr = col[0]
item.Aenderungskennung = col[1]
item.AenderungsDatum = convertStringToInt(col[2])
item.AenderungsZeit = convertStringToInt(col[3])
item.EANladen = convertStringToInt(col[4])
item.EANbestell = convertStringToInt(col[5])
item.Bezeichnung = col[6]
item.Bezeichnung2 = col[7]
item.Bezeichnung3 = col[8]
item.Handelsklasse = col[9]
item.HerstellerInverkehrbringer = col[10]
item.Hersteller = col[11]
item.Herkunft = col[12]
item.Qualitaet = col[13]
item.Kontrollstelle = col[14]
item.MHDRestlaufzeit = convertStringToInt(col[15])
item.WGBNN = convertStringToInt(col[16])
item.WGIfH = convertStringToInt(col[17])
item.WGGH = convertStringToInt(col[18])
item.ErsatzArtikelNr = col[19]
item.MinBestellMenge = convertStringToFloat(col[20])
item.Bestelleinheit = col[21]
item.BestelleinheitsMenge = convertStringToFloat(col[22])
item.Ladeneinheit = col[23]
item.Mengenfaktor = convertStringToFloat(col[24])
item.Gewichtsartikel = convertBnnBool(col[25])
item.PfandNrLadeneinheit = col[26]
item.PfandNrBestelleinheit = col[27]
item.GewichtLadeneinheit = convertStringToFloat(col[28])
item.GewichtBestelleinheit = convertStringToFloat(col[29])
item.Breite = convertStringToInt(col[30])
item.Hoehe = convertStringToInt(col[31])
item.Tiefe = convertStringToInt(col[32])
item.MwstKennung = convertStringToInt(col[33])
item.VkFestpreis = convertStringToFloat(col[34])
item.EmpfVk = convertStringToFloat(col[35])
item.EmpfVkGH = convertStringToFloat(col[36])
item.Preis = convertStringToFloat(col[37])
item.rabattfaehig = convertBnnBool(col[38])
item.skontierfaehig = convertBnnBool(col[39])
item.StaffelMenge1 = convertStringToFloat(col[40])
item.StaffelPreis1 = convertStringToFloat(col[41])
item.rabattfaehig1 = convertBnnBool(col[42])
item.skontierfaehig1 = convertBnnBool(col[43])
item.StaffelMenge2 = convertStringToFloat(col[44])
item.StaffelPreis2 = convertStringToFloat(col[45])
item.rabattfaehig2 = convertBnnBool(col[46])
item.skontierfaehig2 = convertBnnBool(col[47])
item.StaffelMenge3 = convertStringToFloat(col[48])
item.StaffelPreis3 = convertStringToFloat(col[49])
item.rabattfaehig3 = convertBnnBool(col[50])
item.skontierfaehig3 = convertBnnBool(col[51])
item.StaffelMenge4 = convertStringToFloat(col[52])
item.StaffelPreis4 = convertStringToFloat(col[53])
item.rabattfaehig4 = convertBnnBool(col[54])
item.skontierfaehig4 = convertBnnBool(col[55])
item.StaffelMenge5 = convertStringToFloat(col[56])
item.StaffelPreis5 = convertStringToFloat(col[57])
item.rabattfaehig5 = convertBnnBool(col[58])
item.skontierfaehig5 = convertBnnBool(col[59])
item.Artikelart = col[60]
item.Aktionspreis = col[61]
item.AktionspreisGueltigAb = col[62]
item.AktionspreisGueltigBis = col[63]
item.empfVkAktion = convertStringToFloat(col[64])
item.GrundpreisEinheit = col[65]
item.GrundpreisFaktor = convertStringToFloat(col[66])
item.LieferbarAb = col[67]
item.LieferbarBis = col[68]
content.Items = append(content.Items, item)
}
return content, nil
}