foodsoft_article_import/lib/foodsoft_article_import/bnn.rb

97 lines
3.3 KiB
Ruby

# -*- coding: utf-8 -*-
# Module for translation and parsing of BNN-files (www.n-bnn.de)
#
module FoodsoftArticleImport
module Bnn
private
@@codes = Hash.new
@@midgard = Hash.new
# Loads the codes_file config/bnn_codes.yml into the class variable @@codes
def self.load_codes(custom_file=nil)
@gem_lib = File.expand_path "../../", __FILE__
dir = File.join @gem_lib, 'foodsoft_article_import'
begin
@@codes = YAML::load(File.open(File.join(dir,"bnn_codes.yml"))).symbolize_keys
if(custom_file)
custom_codes = YAML::load(File.open(custom_file)).symbolize_keys
custom_codes.keys.each do |key|
if @@codes.keys.include?(key)
custom_codes[key] =custom_codes[key].merge @@codes[key]
end
@@codes = @@codes.merge custom_codes
end
end
@@midgard = YAML::load(File.open(File.join(dir,"midgard_codes.yml"))).symbolize_keys
rescue => e
raise "Failed to load bnn_codes: #{dir}/{bnn,midgard}_codes.yml: #{e.message}"
end
end
public
$missing_bnn_codes = Array.new
# translates codes from BNN to foodsoft-code
def self.translate(key, value)
if @@codes[key][value]
return @@codes[key][value]
elsif @@midgard[key]
return @@midgard[key][value]
elsif value != nil
$missing_bnn_codes << value
return nil
end
end
NAME = "BNN (CSV)"
OUTLIST = false
OPTIONS = {
encoding: "IBM850",
col_sep: ";"
}.freeze
# parses a bnn-file
def self.parse(file, custom_file=nil, **opts)
encoding = opts[:encoding] || OPTIONS[:encoding]
col_sep = opts[:col_sep] || OPTIONS[:col_sep]
self.load_codes(custom_file)
CSV.foreach(file, {col_sep: col_sep, encoding: encoding, headers: true}).with_index(1) do |row, i|
# check if the line is empty
unless row[0] == "" || row[0].nil?
article = {
:name => row[6],
:number => row[0],
:note => row[7],
:manufacturer => self.translate(:manufacturer, row[10]),
:origin => row[12],
:category => self.translate(:category, row[16]),
:unit => row[23],
:price => row[37],
:tax => self.translate(:tax, row[33]),
:unit_quantity => row[22]
}
# TODO: Complete deposit list....
article.merge!(:deposit => self.translate(:deposit, row[26])) if self.translate(:deposit, row[26])
# get scale prices if exists
article.merge!(:scale_quantity => row[40], :scale_price => row[41]) unless row[40].nil? or row[41].nil?
if row[62] != nil
# consider special prices
article[:note] = "Sonderpreis: #{article[:price]} von #{row[62]} bis #{row[63]}"
yield article, :special, i
# Check now for article status, we only consider outlisted articles right now
# N=neu, A=Änderung, X=ausgelistet, R=Restbestand,
# V=vorübergehend ausgelistet, W=wiedergelistet
elsif row[1] == "X" || row[1] == "V"
yield article, :outlisted, i
else
yield article, nil, i
end
end
end
end
end
end