diff --git a/Gemfile b/Gemfile index a6106f2a..01c2cfd7 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,7 @@ gem 'bootsnap', require: false gem 'mysql2' gem 'prawn' gem 'prawn-table' -gem 'haml', '~> 5.0' +gem 'haml' gem 'haml-rails' gem 'kaminari' gem 'simple_form' @@ -62,7 +62,6 @@ gem 'rswag-ui' # we use the git version of acts_as_versioned, and need to include it in this Gemfile gem 'acts_as_versioned', git: 'https://github.com/technoweenie/acts_as_versioned.git' -gem 'foodsoft_article_import', path: 'plugins/article_import' gem 'foodsoft_wiki', path: 'plugins/wiki' gem 'foodsoft_messages', path: 'plugins/messages' gem 'foodsoft_documents', path: 'plugins/documents' diff --git a/Gemfile.lock b/Gemfile.lock index c87f77ae..5b1a9fe7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,14 +16,6 @@ GIT acts_as_versioned (0.6.0) activerecord (>= 3.0.9) -PATH - remote: plugins/article_import - specs: - foodsoft_article_import (0.0.1) - deface (~> 1.0) - rails - roo (~> 2.9.0) - PATH remote: plugins/discourse specs: @@ -242,8 +234,9 @@ GEM rails (>= 4.0.0) globalid (1.0.0) activesupport (>= 5.0) - haml (5.2.2) - temple (>= 0.8.0) + haml (6.1.1) + temple (>= 0.8.2) + thor tilt haml-rails (2.1.0) actionpack (>= 5.1) @@ -553,7 +546,7 @@ GEM sqlite3-ruby (1.3.3) sqlite3 (>= 1.3.3) table_print (1.5.7) - temple (0.10.0) + temple (0.9.1) terser (1.1.13) execjs (>= 0.3.0, < 3) therubyracer (0.12.3) @@ -625,7 +618,6 @@ DEPENDENCIES exception_notification factory_bot_rails faker - foodsoft_article_import! foodsoft_discourse! foodsoft_documents! foodsoft_links! @@ -633,7 +625,7 @@ DEPENDENCIES foodsoft_polls! foodsoft_wiki! gaffe - haml (~> 5.0) + haml haml-rails hashie (~> 3.4.6) i18n-js (~> 3.0.0.rc8) diff --git a/app/models/concerns/localize_input.rb b/app/models/concerns/localize_input.rb index b6330fcc..cfb44a44 100644 --- a/app/models/concerns/localize_input.rb +++ b/app/models/concerns/localize_input.rb @@ -8,7 +8,7 @@ module LocalizeInput separator = I18n.t("separator", scope: "number.format") delimiter = I18n.t("delimiter", scope: "number.format") input.gsub!(delimiter, "") if input.match(/\d+#{Regexp.escape(delimiter)}+\d+#{Regexp.escape(separator)}+\d+/) # Remove delimiter - input.gsub!(separator, ".") or input.gsub!(",", ".") # Replace separator with db compatible character + input.gsub!(separator, ".") # Replace separator with db compatible character input rescue Rails.logger.warn "Can't localize input: #{input}" diff --git a/app/views/articles/_sync_table.html.haml b/app/views/articles/_sync_table.html.haml index 68db9477..ac17adfa 100644 --- a/app/views/articles/_sync_table.html.haml +++ b/app/views/articles/_sync_table.html.haml @@ -32,8 +32,8 @@ = form.text_field 'name', :size => 0 - hidden_fields.each do |field| = form.hidden_field field - %td{:style => highlight_new(attrs, :note)}= form.text_field 'note', class: 'input-medium' - %td{:style => highlight_new(attrs, :manufacturer)}= form.text_field 'manufacturer', class: 'input-medium' + %td{:style => highlight_new(attrs, :note)}= form.text_field 'note', class: 'input-small' + %td{:style => highlight_new(attrs, :manufacturer)}= form.text_field 'manufacturer', class: 'input-small' %td{:style => highlight_new(attrs, :origin)}= form.text_field 'origin', class: 'input-mini' %td{:style => highlight_new(attrs, :unit)}= form.text_field 'unit', class: 'input-mini' %td{:style => highlight_new(attrs, :unit_quantity)}= form.text_field 'unit_quantity', class: 'input-mini' @@ -49,8 +49,8 @@ .input-prepend %span.add-on= t 'number.currency.format.unit' = form.text_field 'deposit', class: 'input-mini', style: 'width: 45px' - %td{:style => highlight_new(attrs, :article_category)} - = form.select :article_category_id, ArticleCategory.all.map {|a| [ a.name, a.id ] }, {include_blank: true} + %td= form.select :article_category_id, ArticleCategory.all.map {|a| [ a.name, a.id ] }, + {include_blank: true}, class: 'input-small' - unless changed_article.errors.empty? %tr.alert %td(colspan=11)= changed_article.errors.full_messages.join(', ') diff --git a/plugins/article_import/app/overrides/articles/upload/replace_label_with_file_format_option.html.haml.deface b/plugins/article_import/app/overrides/articles/upload/replace_label_with_file_format_option.html.haml.deface deleted file mode 100644 index a662d619..00000000 --- a/plugins/article_import/app/overrides/articles/upload/replace_label_with_file_format_option.html.haml.deface +++ /dev/null @@ -1,10 +0,0 @@ -/ insert_after 'erb:contains("file_field")' -- if FoodsoftArticleImport.enabled? - %label(for="articles_file") - %strong="select the file type you are about to upload" - =f.collection_select :type, FoodsoftArticleImport::FORMATS , :to_s, :to_s -/ insert_before 'erb:contains("articles_outlist_absent")' --if FoodsoftArticleImport.enabled? - %label(for="articles_update_category") - = f.check_box "update_category" - = t 'Kategorien aus der Datei übernehmen und erstellen.' \ No newline at end of file diff --git a/plugins/article_import/app/overrides/controllers/articles_controller_override.rb b/plugins/article_import/app/overrides/controllers/articles_controller_override.rb deleted file mode 100644 index 43e9773b..00000000 --- a/plugins/article_import/app/overrides/controllers/articles_controller_override.rb +++ /dev/null @@ -1,18 +0,0 @@ -ArticlesController.class_eval do - def parse_upload - uploaded_file = params[:articles]['file'] or raise I18n.t('articles.controller.parse_upload.no_file') - type = params[:articles]['type'] - options = { filename: uploaded_file.original_filename } - options[:outlist_absent] = (params[:articles]['outlist_absent'] == '1') - options[:convert_units] = (params[:articles]['convert_units'] == '1') - options[:update_category] = (params[:articles]['update_category'] == '1') - - @updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_from_file uploaded_file.tempfile, type, options - if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty? - redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.parse_upload.notice') - end - @ignored_article_count = 0 - rescue => error - redirect_to upload_supplier_articles_path(@supplier), :alert => I18n.t('errors.general_msg', :msg => error.message) - end -end diff --git a/plugins/article_import/app/overrides/models/article_override.rb b/plugins/article_import/app/overrides/models/article_override.rb deleted file mode 100644 index 2018a4e7..00000000 --- a/plugins/article_import/app/overrides/models/article_override.rb +++ /dev/null @@ -1,37 +0,0 @@ -Article.class_eval do - def unequal_attributes(new_article, options = {}) - # try to convert different units when desired - if options[:convert_units] == false - new_price = nil - new_unit_quantity = nil - else - new_price, new_unit_quantity = convert_units(new_article) - end - if new_price && new_unit_quantity - new_unit = self.unit - else - new_price = new_article.price - new_unit_quantity = new_article.unit_quantity - new_unit = new_article.unit - end - - attribute_hash = { - :name => [self.name, new_article.name], - :manufacturer => [self.manufacturer, new_article.manufacturer.to_s], - :origin => [self.origin, new_article.origin], - :unit => [self.unit, new_unit], - :price => [self.price.to_f.round(2), new_price.to_f.round(2)], - :tax => [self.tax, new_article.tax], - :deposit => [self.deposit.to_f.round(2), new_article.deposit.to_f.round(2)], - # take care of different num-objects. - :unit_quantity => [self.unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f], - :note => [self.note.to_s, new_article.note.to_s] - } - if options[:update_category] == true - new_article_category = new_article.article_category - attribute_hash[:article_category] = [self.article_category, new_article_category] unless new_article_category.blank? - end - - Article.compare_attributes(attribute_hash) - end -end diff --git a/plugins/article_import/app/overrides/models/supplier_override.rb b/plugins/article_import/app/overrides/models/supplier_override.rb deleted file mode 100644 index 504bc26d..00000000 --- a/plugins/article_import/app/overrides/models/supplier_override.rb +++ /dev/null @@ -1,51 +0,0 @@ -Supplier.class_eval do - # Synchronise articles with spreadsheet. - # - # @param file [File] Spreadsheet file to parse - # @param options [Hash] Options passed to {FoodsoftArticleImport#parse} except when listed here. - # @option options [Boolean] :outlist_absent Set to +true+ to remove articles not in spreadsheet. - # @option options [Boolean] :convert_units Omit or set to +true+ to keep current units, recomputing unit quantity and price. - def sync_from_file(file, type, options = {}) - all_order_numbers = [] - updated_article_pairs, outlisted_articles, new_articles = [], [], [] - custom_codes_path = File.join(Rails.root, "config", "custom_codes.yml") - opts = options.except(:convert_units, :outlist_absent) - custom_codes_file_path = custom_codes_path if File.exist?(custom_codes_path) - FoodsoftArticleImport.parse(file, custom_file_path: custom_codes_file_path, type: type, **opts) do |new_attrs, status, line| - article = articles.undeleted.where(order_number: new_attrs[:order_number]).first - - if new_attrs[:article_category].present? && options[:update_category] - new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) || ArticleCategory.create_or_find_by!(name: new_attrs[:article_category]) - else - new_attrs[:article_category] = nil - end - - new_attrs[:tax] ||= FoodsoftConfig[:tax_default] - new_article = articles.build(new_attrs) - if status.nil? - if article.nil? - new_articles << new_article - else - unequal_attributes = article.unequal_attributes(new_article, options.slice(:convert_units, :update_category)) - unless unequal_attributes.empty? - article.attributes = unequal_attributes - updated_article_pairs << [article, unequal_attributes] - end - end - elsif status == :outlisted && article.present? - outlisted_articles << article - - # stop when there is a parsing error - elsif status.is_a? String - # @todo move I18n key to model - raise I18n.t('articles.model.error_parse', :msg => status, :line => line.to_s) - end - - all_order_numbers << article.order_number if article - end - if options[:outlist_absent] - outlisted_articles += articles.undeleted.where.not(order_number: all_order_numbers + [nil]) - end - [updated_article_pairs, outlisted_articles, new_articles] - end -end diff --git a/plugins/article_import/foodsoft_article_import.gemspec b/plugins/article_import/foodsoft_article_import.gemspec deleted file mode 100644 index b030005f..00000000 --- a/plugins/article_import/foodsoft_article_import.gemspec +++ /dev/null @@ -1,20 +0,0 @@ -$:.push File.expand_path("../lib", __FILE__) - -# Maintain your gem's version: -require "foodsoft_article_import/version" - -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "foodsoft_article_import" - s.version = FoodsoftArticleImport::VERSION - s.authors = ["viehlieb"] - s.email = ["foodsoft@local-it.org"] - s.summary = "Manages manual article import from file. File Formats supported are: foodsoft file(csv), bnn files (.bnn) and odin files (xml)" - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"] - - s.add_dependency "rails" - s.add_dependency "deface", "~> 1.0" - s.add_dependency 'roo', '~> 2.9.0' - s.add_development_dependency 'simplecov' -end diff --git a/plugins/article_import/lib/foodsoft_article_import.rb b/plugins/article_import/lib/foodsoft_article_import.rb deleted file mode 100644 index 4472cca5..00000000 --- a/plugins/article_import/lib/foodsoft_article_import.rb +++ /dev/null @@ -1,77 +0,0 @@ -# frozen_string_literal: true -require "deface" -require 'foodsoft_article_import/engine' -require 'digest/sha1' -require 'tempfile' -require 'csv' -require 'yaml' -require 'active_support/core_ext/hash/keys' -require_relative 'foodsoft_article_import/bnn' -require_relative 'foodsoft_article_import/utf8_encoder' -require_relative 'foodsoft_article_import/odin' -require_relative 'foodsoft_article_import/foodsoft' -module FoodsoftArticleImport - class ConversionFailedException < StandardError; end - - FORMATS = %w(bnn foodsoft odin).freeze - def self.enabled? - FoodsoftConfig[:use_article_import] - end - - def self.file_formats - @@file_formats ||= { - 'bnn' => FoodsoftArticleImport::Bnn, - 'foodsoft' => FoodsoftArticleImport::Foodsoft, - 'odin' => FoodsoftArticleImport::Odin, - }.freeze - end - - # Parse file by type (one of {.file_formats}) - # - # @param file [File, Tempfile] - # @option opts [String] type file format (required) (see {.file_formats}) - # @return [File, Roo::Spreadsheet] file with encoding set if needed - def self.parse(file, custom_file_path: nil, type: nil, **opts, &blk) - @@filename = opts[:filename] if opts[:filename] - custom_file_path ||= nil - type ||= 'bnn' - parser = file_formats[type] - if block_given? - parser.parse(file, custom_file_path: custom_file_path, &blk) - else - data = [] - parser.parse(file, custom_file_path: custom_file_path) { |a| data << a } - data - end - end - - # Helper method to generate an article number for suppliers that do not have one - def self.generate_number(article) - # something unique, but not too unique - s = "#{article[:name]}-#{article[:unit_quantity]}x#{article[:unit]}" - s = s.downcase.gsub(/[^a-z0-9.]/, '') - # prefix abbreviated sha1-hash with colon to indicate that it's a generated number - article[:order_number] = ":#{Digest::SHA1.hexdigest(s)[-7..]}" - article - end - - # Helper method for opening a spreadsheet file - # - # @param file [File] file to open - # @param filename [String, NilClass] optional filename for guessing the file format - # @param encoding [String, NilClass] optional CSV encoding - # @param col_sep [String, NilClass] optional column separator - # @return [Roo::Spreadsheet] - def self.open_spreadsheet(file, encoding: nil, col_sep: nil, liberal_parsing: nil) - opts = { csv_options: {} } - opts[:csv_options][:encoding] = encoding if encoding - opts[:csv_options][:col_sep] = col_sep if col_sep - opts[:csv_options][:liberal_parsing] = true if liberal_parsing - opts[:extension] = File.extname(File.basename(file)) if file - begin - Roo::Spreadsheet.open(file, **opts) - rescue StandardError => e - raise "Failed to parse foodsoft file. make sure file format is correct: #{e.message}" - end - end -end diff --git a/plugins/article_import/lib/foodsoft_article_import/bnn.rb b/plugins/article_import/lib/foodsoft_article_import/bnn.rb deleted file mode 100644 index b07b9e45..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/bnn.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -# Module for translation and parsing of BNN-files (www.n-bnn.de) -# -module FoodsoftArticleImport - module Bnn - @@codes = {} - @@midgard = {} - # Loads the codes_file config/bnn_codes.yml into the class variable @@codes - def self.load_codes(custom_file_path = nil) - @gem_lib = File.expand_path '..', __dir__ - dir = File.join @gem_lib, 'foodsoft_article_import' - begin - @@codes = YAML.safe_load(File.open(File.join(dir, 'bnn_codes.yml'))).symbolize_keys - if custom_file_path - custom_codes = YAML.safe_load(File.open(custom_file_path)).symbolize_keys - custom_codes.each_key do |key| - custom_codes[key] = custom_codes[key].merge @@codes[key] if @@codes.keys.include?(key) - @@codes = @@codes.merge custom_codes - end - end - @@midgard = YAML.safe_load(File.open(File.join(dir, 'midgard_codes.yml'))).symbolize_keys - rescue StandardError => e - raise "Failed to load bnn_codes: #{dir}/{bnn,midgard}_codes.yml: #{e.message}" - end - end - - $missing_bnn_codes = [] - - # translates codes from BNN to foodsoft-code - def self.translate(key, value) - if @@codes[key][value] - @@codes[key][value] - elsif @@midgard[key] - @@midgard[key][value] - elsif !value.nil? - $missing_bnn_codes << value - nil - end - end - - NAME = 'BNN (CSV)' - OUTLIST = false - OPTIONS = { - encoding: 'IBM850', - col_sep: ';' - }.freeze - - # parses a bnn-file - def self.parse(file, custom_file_path: nil, **opts) - custom_file_path ||= nil - encoding = opts[:encoding] || OPTIONS[:encoding] - col_sep = opts[:col_sep] || OPTIONS[:col_sep] - load_codes(custom_file_path) - 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: UTF8Encoder.clean(row[6]), - order_number: row[0], - note: UTF8Encoder.clean(row[7]), - manufacturer: translate(:manufacturer, row[10]), - origin: row[12], - article_category: translate(:category, row[16]), - unit: row[23], - price: row[37], - tax: translate(:tax, row[33]), - unit_quantity: row[22] - } - # TODO: Complete deposit list.... - article.merge!(deposit: translate(:deposit, row[26])) if translate(:deposit, row[26]) - - 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 diff --git a/plugins/article_import/lib/foodsoft_article_import/bnn_codes.yml b/plugins/article_import/lib/foodsoft_article_import/bnn_codes.yml deleted file mode 100644 index dfb226e7..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/bnn_codes.yml +++ /dev/null @@ -1,1119 +0,0 @@ -# BNN Codes -tax: - "1": 7.0 - "2": 19.0 - "3": 10.7 - -deposit: - "930190": 0.08 - "930200": 0.08 - "930205": 0.08 - "930210": 0.08 - "930230": 0.08 - "930260": 0.08 - "930270": 0.08 - "930280": 0.08 - "998010": 0.08 - "998016": 0.08 - "998350": 0.08 - "998360": 0.08 - "998427": 0.08 - "998440": 0.08 - "998460": 0.08 - "998470": 0.08 - "998500": 0.08 - "998510": 0.08 - "998700": 0.08 - "998710": 0.08 - "998725": 0.08 - "998730": 0.08 - "998750": 0.08 - "998760": 0.08 - "998790": 0.08 - "998800": 0.08 - "998810": 0.08 - "998840": 0.08 - "998860": 0.08 - "998880": 0.08 - "998887": 0.08 - "900010": 0.15 - "900020": 0.15 - "900030": 0.15 - "900040": 0.15 - "900050": 0.15 - "900070": 0.15 - "900075": 0.15 - "900085": 0.15 - "900089": 0.15 - "900850": 0.15 - "900860": 0.15 - "900870": 0.15 - "900890": 0.15 - "930010": 0.15 - "930020": 0.15 - "930030": 0.15 - "930035": 0.15 - "930050": 0.15 - "930090": 0.15 - "930110": 0.15 - "930120": 0.15 - "930130": 0.15 - "930320": 0.15 - "930325": 0.15 - "955230": 0.15 - "998000": 0.15 - "999983": 0.15 - "999985": 0.15 - "998040": 0.15 - "998060": 0.15 - "998070": 0.15 - "998080": 0.15 - "998100": 0.15 - "998110": 0.15 - "998300": 0.15 - "998310": 0.15 - "998320": 0.15 - "998330": 0.15 - "998340": 0.15 - "998352": 0.15 - "998370": 0.15 - "998380": 0.15 - "998390": 0.15 - "998405": 0.15 - "998417": 0.15 - "998450": 0.15 - "998480": 0.15 - "998520": 0.15 - "999200": 0.15 - "900892": 0.25 - "930290": 0.25 - "999980": 0.25 - "998020": 0.25 - "998030": 0.25 - "998090": 0.25 - "998366": 0.25 - "998420": 0.25 - "998437": 0.25 - "998740": 0.25 - "998770": 0.25 - "930450": 0.50 - "930440": 1.00 - "930460": 1.00 - "930256": 1.50 - "930257": 1.50 - "930250": 30.00 - "930252": 30.00 - "998720": 30.00 - "998830": 30.00 - "998870": 30.00 - -manufacturer: - bro: Brodowin - AAB: Azienda Agricola Bettili - ABD: Agro Bio Drom, Frankreich - ABM: Maintal GmbH - ABT: Albtal Naturkost GmbH - ACF: Arcada France S.A. - ACL: Achleitner Biohof GmbH - ADC: Coste Vincent & Francoise - ADM: Antersdorfer Mühle GmbH - ADR: Faan Zuidhorn - AFH: Doris Wallbaum & Co - agm: Angermeier Weinimport - AGR: Agrano GmbH & Co KG - AGX: Agrexco Ltd. - akr: Biohof Barnsen - ALB: Alber Pilzkonservenfabrik - alf: Bioland-Hof Altfeld - ALL: Allgäuland Käsereien GmbH - ALM: Allmendinger Metzgerei - ALN: AL Naturkost Handels GmbH - ALO: Allos-Walter Lang GmbH - ALR: Allerleirauh GmbH - ALS: Alsan Werk - ALT: Alberts-Tofuhaus - ALV: Alva - AMA: Amazonas Naturpr.Handels GmbH - AMS: Santa Fe Europe GmbH - AMW: AlmaWin GmbH - AND: Andechser Molkerei GmbH - ANF: Allgäu Natur GmbH - ANG: Angelmaier OHG - ANI: Anis de l' Abbaye - ANJ: Atelier Niedernjesa - ANL: Anderlbauer Frasdorf - ANN: AN, Ne Bienenwachskerzen - ANT: Antico Forno a Legna - APR: Apeiron - ARC: Arche Naturprodukte GmbH - ARG: ARGANDÓR - ARI: Aries Umweltprodukte - ARO: Aromabalance, Silvia Plum - art: Artesia - asc: Asch - ASS: Assindia - GmbH - ATX: Ute Arnswald - AUR: Auro Pflanzenchemie AG - BAB: Baba-Laffa, W. Maguid - BAC: Hof Backensholz - BAE: Biofarm A.E. - bai: Bioland-Hof Gerhard Baiker - bäj: Bärthele, Joachim - BAK: Bauckhof demeter Naturkost - BAL: Ballybrado, Cahir Co. - BAS: Bastiaansen Bio-Kaas B.V. - BAU: BioBauernmarkt Chiemgau eG - bba: Bäckerei Bahde - bbi: Bäckerei Bihn - BBN: Bio Bavaria Naturkost - BBO: Flemming Naturkost - BBR: Mineralbrunnen AG - BBW: Bioland Ba-Wü GmbH - bdh: Butendiek-Hof - bdp: Biodynaminska Produkter - BDW: Bio-Dienst Weiss GmbH - BEL: Bellenature - BER: Bergquell GmbH & Co.KG - BEU: Beutelsbacher GmbH - BFA: Biofarms s.r.l. - BFG: Burkhardt Feinkostwerke GmbH - BFR: Bioforce A.Vogel GbmH - BFS: Bruno Fischer GmbH Naturkost - bgb: Heinz Bursch - BGH: Burgunderhof digestif´s GmbH - BHÄ: Bäck. Härdtner - bhb: Bäckerei Höhenberg - bhc: Bioland-Hof Christiansen´s - bhk: Bioland-Hof Klauser - bhl: Bioland Hof Lesker KG - bhm: Bioland-Hof Hubert Merz - BHO: Barnhouse Naturprodukte GmbH - bhö: Bioland-Hof Hörz - bhr: Bioland-Hof Martin Häring - BIA: Bio Aras, ELAFOS - BIB: Bio Bärchen Vertriebs GmbH - bid: Imkerei Binder - BIF: Biofrisch GmbH - BIH: Markus Bihler GmbH - bil: BioHof Laurer - bim: Bieringer Mühle - BIN: Bingenheimer Saatgut AG - BIO: Bio Akademie - BIP: Bio Plus GmbH - BIR: Käserei H. Birkenstock GmbH - BIS: Bio Service SRL - BIT: Bioturm - BIV: BioVita Naturkost GmbH - BIZ: Biozyklische Produkte AG - BJS: Josef Schäfers - BKB: Bio Korn Biscuits - bkf: Bakenhus Biofleisch GmbH - bkh: Bauckhof OHG - BKM: Biokosma GmbH - bko: Bäckerei Kostner - BKP: Brava cv - BKT: Biokorntakt Vertriebs GmbH - BKW: Liane und Roman Wirth - BLA: biolare ? Pilzanbau - BLB: Blütenland Bienenh. - blg: Bollinger, Bernd - BLI: Holle Baby Food GmbH - BLL: Boller Fruchtsäfte - BLM: Binger Lammbräu GmbH - BLN: Bioland GmbH Nord - BLR: Ökofrost GmbH - BLS: Bioland Südtirol - BMA: BIOMAS - BMK: N.V. Biomilk S.A. - BML: Bio Molkerei Lembach - bms: Bioland-Milchschafhof - bmü: Bannmühle - bmw: Barbara Müller Handels GmbH - BND: Bionade GHmbH - BNE: Bionest - BOA: Bio-Obst Augustin KG - BOB: Bobalis - BOH: Boschenhof GbR - BOI: Bois Naturkost GmbH - BOK: Bodensee Kelterei GmbH - BOL: Bohlsener Mühle - böm: BÖMO - BON: Allos Walter Lang GmbH - bos: Biol-Dyn. Obstbau Seger - BOW: Gandha BV - BPL: F.J. Moog SARL - BPR: Bioprim - bra: Brack Kaffee - brb: Rüdiger Born - BRE: Gewürzmühle Brecht GmbH - BRI: Brio Spa - BRO: Jules Brocherin S.A. - brs: Asgaard - BRT: Candy Factory KG - bru: Biolandhof Brummer-Bange - bsh: Bioland Schleswig-Holstein - BSK: Wiggensbach GmbH - bsp: Bioland-Hof Speidel - bsw: Bioland-Hof Schulte-Walter - BTH: Biothek Handels-GmbH - btm: EZG Bioland-Südgetreide - BTR: Biotropic GmbH - BUC: Bucheckchen - BUF: Bodin & Fils - BÜH: Metzgerei Bühler GmbH - BUK: Borghoff & Kötter Gbr - bup: Braun U. Partner - BUR: Burk's Fränkische Öko-Nudeln - BVE: Bio Vegan GmbH - bvg: Bioland Vermarktungs GmbH - BVI: abacco B.V. - BWH: Bornwiesenhof - BWL: Haya Lebensmittel GmbH - BYO: Byodo Naturkost GmbH - CAA: Coop.Agr. ARABIOS.a.r.l. - CAB: Erich Boden Delikatessen - CAL: Calendula Naturkost Backstube - CAM: Campobelle s.r.l. - can: Anthal Canadi - CAR: Care Naturkost GmbH & Co. - CAV: Cal Valls - CBR: C. Berger - CBU: Weingut Clemens Busch - CDO: Cha Do Teehandel - CES: Il Cesto - CGL: Castiglioni S.P.A. - CHE: Chemviron Carbon gmbH - CHI: Chiemgauer Naturfleisch GmbH - CHR: De Rit Handels GmbH - CLO: Clostermann - CMD: CMD Naturkosmetik - CNH: Chiemgauer Naturkosthandel - COL: Chocolat Schönenberger AG - COR: C&C Fine Foods, Niederlassung - COS: Cosmoveda, G. Eckerle - CTE: Castle Tea - CUM: Cumnatura - CVE: Campina Verde ecosol S.L. - DAG: De Dageraad - DAK: Die andere Konditorei - DAM: Dachswanger Hof - DAN: Danival - DAV: Davert GmbH - DBB: Die Beerenbauern - DBH: CW Öko Ei GmbH - DDC: Domain de Clairac, Frankreich - DDI: Demeter Dienste - DDM: Domaine du Midi GmbH - DEH: Bio-Hofmolkerei Dehlwes - DEN: dennree-Versorgungs GmbH - DET: Detmers Getreide GmbH - DFE: Demeter Felderzeugnisse GmbH - DFR: Daniel Frank - DGU: Dal Gustaio - DIE: Helmut Arendt - DIN: Alfons u. Franz Neumeier GbR - dio: Dionisio de Nova Garcia - dis: Schulze-Schleppinghoff - DIW: Weingut Hans Diwald - DKA: Dr. Klaus Karg - DKG: Geifertshofen GmbH - dko: Disselkoen Organics - dma: Demeterhof Massmann - dmä: Demeterhof Mäck - dnj: Danner, Johann Georg - DOT: Dottenfelder Hof - dpr: Demeterhof Preller - DRM: Dr. Martins da Cunha GmbH - DSE: Deutsche See - dsw: Dirk Schulze-Wethmar - DUN: Dunn's of Dublin - DWE: Dwersteg Destillerie - DWF: Dworschak-Fleischmann GbR - dwp: Dritte Welt Partner - DYF: Dynamis France - DZW: De Zwalm - EBR: Die Regionalen - ECO: Ecomel B.V. - ECP: ecopan-Naturkost GmbH - ecr: Ecoregion - ECV: ECOVER Products nv - EGG: Eggert´s Tiefkühl-Service - EGL: Wilhelm Egle GmbH - EGM: Ökoland GmbH - EIQ: Ei.Q. GmbH - EIS: Eisblümerl Naturkost - eit: Eitzinger Franz - ELK: Naturkost Elkershausen GmbH - EOG: EOS Getränke GmbH - EOS: Eosta International BV (NL) - EPI: epikouros - ERD: ErdmannHauser GmbH - ERH: Frank Erhardt - ERN: ERNTESEGEN Naturkost GmbH - EUH: Eurohealth AG - EUN: Euronat ? Bretagne - EVS: Evers Naturkost GmbH - EWE: Ernst Weber Naturkost - fah: FairHandeln - FAI: Frucht Agentur Iberia - FAL: Breisgaumilch GmbH, Fallers - FDO: Fattoria degli Orsi - fig: Fattoria degli Orsi - FIN: Finck - fis: Brauerei Rupert Fisch - FIT: Fitne GmbH - FKS: Hermann Stiefel - FKW: Fruchsaftkelterei Klaus Weber - FLA: Flamant Vert S.A.R.L. - FLC: Flockenhaus - fle: Fleckenbühler Landprodukte - FLN: Flemming-Naturkost - FLO: Florin, Angelika Trankle - FLP: Fleur Products BV - FON: Fontaine Nahrungsmittel GmbH - FOR: Forte - FÖR: Förster - FPF: Fahrenzhausen GmbH - fps: Franz Baumann - FRC: Francia Mozzarella - FRE: Hofladen Frey - FRH: Freiheithof - FRI: Frisetta GmbH - FRK: Frischkeim Naturkost GmbH - FRO: Fromin GmbH - FRT: Florentin-Mediterranean Food - FVG: FALA Verkaufsgesellschaft mbH - FZI: Feinkäserei Zimmermann - FZS: Sommer & Co.KG - gah: Gärtnerei Amaranth - gäh: Gärtnerei Halmberg - gäk: Gärtnerei Kienast - gal: Gallung´s Ziegenhof - GAR: Gärtnerei Landes - GBA: Gerald Bartke GmbH - gch: Gärtnerei Christian Hiss - gcl: Gut Clarenhof - gdi: Gärtnerei Distel - GDR: Graindrops - GEB: Martina Gebhardt GmbH - GEE: Lupina Handels GmbH - GEH: Georg Gehrsitz GmbH & Co.KG - GEP: GEPA - GFH: Mechthild & Andres Klose - GFR: Gebr. Franz GmbH - ggk: Burkhard Dreckel - gha: Gärtnerei Andreas Hankel - gho: Gärtnerei Horizont - gie: Giegold Hefefabrik - gip: Gilchinger Pilzzucht - gks: Gärtnerei Klein Sigi - GLG: Glafey-Lichte GmbH - gli: Glitz Ehringhausen - GLM: Gläserne Meierei GmbH - GOL: Golden Temple - GÖM: Grünsfelder GmbH & Co.KG. - gom: Gomille, Torsten - GOV: Govinda?s Naturkost GbR - gpb: Gerhard Preuschl Biolandhof - gpe: Gesa Petersen - GPN: Grüner Punkt Naturkost GmbH - GRE: C.F. Grell Nachf. - GRM: Grindsted Mejeri - GRN: Biotropic GmbH - GRU: Gruel Biolandhof - GSD: Gerhard Schürholz GmbH - GSE: GSE Vertrieb - gsi: Gregor Sing - gsl: Gärtnerei Schmälzle - gub: Gärtnerei Ulenburg - GUD: Gude GmbH - GUL: Gesund & Leben - GUR: Gurtmann, Christoph - GUT: Gute Zeiten GmbH - GUZ: Glahn & Zindl - GWF: GWF eG - HAA: Haaner Felsenquelle GmbH - hag: Hartmann Getränke - hal: Haldenhof - HAM: Hamfelder Hof - HAN: Handelskontor Willmann - HÄR: Härle - HAU: Dr. Hauschka ? Wala GmbH - HAW: hawo´s Getreidemühlen GmbH - HBG: Hornberger Lebensquell - hdk: Hof Dinkler - HEC: Heuck Landbäckerei - HEI: Heidelberger Naturfarben - hek: Hecker Naturkost - HER: Herbaria Kräuterparadies GmbH - HES: Weingut Heiner Sauer - HEU: Heuschrecke Naturkost GmbH - hex: Hexerküche - HFA: Hof Farrenau, Deimling GbR - hfm: Hofgemeinschaft Fischermühle - hfn: Hofgemeinschaft Fischermühle - hgo: Imkerei Oswald - hha: Hasso Hasbach - HIE: Hierl- Der Nudelmacher - HIN: Mathias Kloppenborg GmbH - HKH: Hofkäserei Heggelbach - hkk: Hekking - HLE: Holzlehner - HLW: Herrmannsdorfer Werkstätten - HMB: Humbel Brennerei - HMS: Handelsag. Rolf Schekerka - HMÜ: Peter & Martina Linxweiler - HOC: Hoch GmbH Oblatenfabrik - hof: Hofmark Brauerei - hoh: Dorfgem. Hohenroth - hoi: Henri Willig B.V. - HOL: Holle Baby Food GmbH - HÖL: Höllensprudel - hom: Hoffmeier - HOR: Horizon Natuurvoeding B.V. - HÖR: Bäckerei Hörtling - HOV: H2Ovital oHG - HOY: Hoyer GmbH - HPG: Horn Papiergroßhandel - hse: Herbert Seitz - hst: Hof Steinrausch - hum: Huber, Martin - HUN: hanf & natur - HUZ: Huzo - hwi: Henri Willig, Kaasm. - HWL: Hawlik Pilzbrut GmbH - IAB: Imkerei (Reiner) Bienefeld - ibe: Imkerei Berrenrath - ilk: Imkerei Ludger Klinker - ILU: ILUMINA GmbH - imb: Imkerei Betz - IMF: Hain Celestial Europe BVBA - imm: Mohr + Müller Imkerei - irf: Imkerei Feldt - IRM: Imkerei Roland Maier - ISA: ISANA GmbH & Co.KG - ISE: Klaus Wolf - ISK: Isko Vertriebs GmbH - IUM: I&M Inge Stamm GmbH - jäh: Jähnke Naturkost - JAN: BioFleischerei Jansen - JAS: Jasci Donatello - JAT: Jatex Handels-GmbH - jbe: Beck Schafhof - JOP: Jogopur Yogoferm GmbH - JOR: Jordan Cereals Ltd. - KÄB: (Martin) Bauhofer Käserei - KÄL: Inntaler GmbH - KAM: KAMUT Association of Europe - KAN: Kanne Brottrunk GmbH & Co.KG - KAT: Karibu Trade - kbh: Kiebitzhof - KBW: Klosterbrauerei Weißenohe - kei: Keil, Sepp - KER: Keramik & Kerzen - kgg: Kelterei Gregor Greimel - KGÖ: Karl Gröner GmbH - KGV: Klostergut Volkenroda - KHA: Konrad Halder - KIL: Kilian - KIP: Kipepeo BIO & FAIR GmbH - KKL: KKL-Naturwaren - KKV: Vollwertbäckerei König - KLA: AlmaWin GmbH - KLD: Keimland - KLG: Keimling Naturkost GmbH - klk: Käserei Schlierbach - klo: Klotz, Martin - KMF: Käsemanufaktur, Lothar Müller - KNE: Getreidemühle Knecht KG - KNÖ: Robert Knöbel - KON: Engelhard GmbH & Co. KG - KOR: Kornblume, F.+ B.Brinkmann - KPL: Kräutergarten Pommernland - KRA: Kranichhof - KRÄ: KAULFUSS - KRE: Krämers Ernährung - krr: Fachkrankenhaus Ringgenhof - KTO: Kato - KUC: Kolla & Co - KWE: Köhlerei Wengert - LAB: Labroco Agrarconsult - LAF: Hofgut Algertshausen - LAL: La Luna del Rospo - läm: Lämmerhof - LAN: Landkrone GmbH - LAS: Lakhsmi - LAV: laverana GmbH - LBI: Do-it Dutsch - LEB: U. Walter GmbH - Lebensbaum - LHQ: St. Leonhardquelle - LIL: Legend International Ltd. - LIM: Lima NV - LIR: Lily Rose - LIW: Lichtwurzel, Imton - LJL: Johann Langgartner - LMC: Lammersiek & CO. - LNA: Grabower Süßwaren GmbH - LÖC: Löcke Bio-Pilzzucht - LOG: Logona Hans Hansel GmbH - LSP: La Spinosa ( Weingut) - LTA: Lauretana, Wasser Import GmbH - LUB: Lubs GmbH - lüp: Lübcke Papier GmbH & Co KG - LUV: Luvos Heilerde - MAB: Bio-Nahrungsmittel GmbH - mah: Hof Mahlitzsch - MAI: Maisch - map: Maple GmbH - MAR: Marschland NK GmbH - MÄR: Märkisches Landbrot GmbH - MAT: Martinshof GmbH - MÄU: Gebr. Grund GmbH & Co.KG - MAY: Mayka Naturbackwaren GmbH - MAZ: Mazer, Bernd - MCA: Mustiola International SRL - med: Medousa, Griechenland Importe - MEK: Weingut Meinklang - met: Metsä Tissue GmbH - MGN: Naturland-Bauern e.G. - mhb: Meyerhof Belm - mhh: ?Die Meierei? Hansfelder Hof - MID: Midi - mig: Migliore - mil: Miller GmbH & Co.KG Agnes - MKF: merkur frucht Freiburg GmbH - MKL: Makulaku Confectionery Ltd - MLL: Mollis Kinderprodukte GmbH - MMC: MM Cosmetic GmbH - MOA: MolenAartje B.V. Natudis - MOB: Frisetta GmbH & Co.KG - MOC: Wasserprinz; div. Anbieter - MOI: Moin BioTK-Bachwaren - MOK: Mokobella EU GmbH - MOL: Moltex Baby-Hygiene GmbH - MOR: EgeSun GmbH - MÖR: Mörk Naturkostprodukte - MOU: Wertform GmbH & Co - MSV: mesa verde - MTB: Mont´Albano - MUL: Multikost Vertriebs GmbH - MWO: Milchwerke Oberfranken - MZG: Sieben Zwerge GmbH - mzi: Mathias Zipf - NAB: Hubert Tempelmann e.K. - NAC: BodyWise (UK)Ltd. - NAG: Tofumanufaktur Nagel GmbH - NAM: Naturmaelk A.m.b.a. - NAP: Combu Cha - NAT: Naturata e.G. - nbm: Nußbaumer, Roman - NBO: Nürnberger Bio-Originale - NCO: Natur Compagnie GmbH - NEE: Neue Erde GmbH - NEG: Neu´s GmbH & Co. KG - NEU: Gebr. Ehrnsperger e.K. - nhb: Naturlandhof Biberger - NHU: Natur Hurtig (Himalaya Salz) - nlg: Nordland, Lebensgem. - NMA: NaturMarkt GmbH - nmd: Münzner - NNA: Mensch & Natur AG - NOK: Noka-Sojamanufaktur GmbH - NPG: Nette Papier GmbH - NSC: Naturkost Schuchardt - NTM: Natumi GmbH Produkte & Ideen - NTR: Naturian Ökoweine OHG - NTU: Naturion - NUR: IL NURAGHE GmbH - NUT: Nutrifors AG - NWA: Nikolaihof Wachau - Weingut - NWR: Öko-Norm GmbH - OAT: Ceba Foods AB - obb: Obsthof Bruno Brugger - obm: Obsthof Bernd Majer - OBS: Öko-Bauernhöfe Sachsen GmbH - ÖBW: Brodowin Ökodorf - OCB: OCB-Vertriebs-GmbH - ODE: Odenwald EKO Brood en Banket - ODI: ODIN Holland C.V. - ÖER: Öko Ernte GmbH - ÖFA: Öko Feinkost Andechs Gmbh - ÖFR: Ökofrost GmbH - ogh: Demeter Gärtnerei Obergrashof - ohc: Obsthof Cordes - OHE: Obsthof Heinrich - ohh: Obsthof Hermann Helde - OHL: Ohling, Andreas - ÖKB: ÖkoBo - ÖKH: Ökohum Vertriebs GmbH - ÖKL: Ökoland GmbH Nord - ÖKN: Ökonatur - ÖKU: Naturkosthandel Ökollus - ÖLI: Öko-Line - ÖMA: ÖMA- Beer GmbH - OML: Ostermühle Naturkost GmbH - ÖMS: Ölmühle Solling GmbH - ORG: Organix4U GmbH - ORH: Obsthof Robert Hartmann - ORO: Organic Oils S.P.A. - ort: Biofrucht Ortlieb GbR - osn: Osning-Getränke GmbH - ÖWK: Haus am Goldberg GmbH - ÖWR: Weingut Richard Schmidt - ÖWS: Öko-Weinimport Schmid - pab: Bacchini Roberto & C. S.n.c. - PAN: Pasta Nuova GmbH - pau: Bioland Gemüse Paul - PEM: PEMA Heinrich Leupoldt KG - PER: Perger Getränke GmbH - PET: Marcel Petite, Frankreich - PFH: Gabriele Gersdorf GmbH - PFO: Papierf. Oberschmitten GmbH - PID: MW BGL Chiemgau eG - PIM: Pinzgauer Molkerei - PIN: Pinkus Müller GmbH & Co.KG - PLA: Käserei Plangger Ges.m.b.H. - PLG: Peralge, Marciella Callegarie - PLO: div. Anbieter - PMI: Peterstaler Mineralquellen - PMP: Progeo Mangimi Petfood - PNA: Pro Natura S.A. - PÖB: Pötzelberger - pod: Poder GmbH - PÖS: PINGU-Öko-Tiefkühlservice - PRG: Provence Regime S.A. - PRN: Pro Natur GmbH - PRO: Probio Handelsgesellschaft - PRV: Provamel - PVL: Primavera Life GmbH - RAA: Raab - RAC: Rachelli Italia s.r.l. - rad: Radicula GmbH (Avalon) - ran: Randegger Ottilienquell - RAP: Rapunzel Naturkost AG - RBB: Michael Krieger KG - rde: Roman Denis Bioland-Gemüsebau - rds: Rudolf Schramm - RED: Redecker - rei: Reicheneder, Gerhard - rha: Hofgut Rengoldshausen - RHG: Rheinland-Höfe GmbH - RHÖ: Rhöner (Brauerei) - RIE: Peter Riegel Weinimport GmbH - RIN: Ringenwalde Werkhof - RIS: Ristic - RIT: De Rit Handels GmbH - RLG: Metzgerei Rieblinger - ROB: Geflügelhof RoBert?s - rog: Söbbeke GmbH & Co. KG - ROH: Geflügelhof Rothäusle - ROL: C. F. Rolle Mühle GmbH - ROM: Rosmarin Ingo Karrasch GbR - ROS: Hubmann- Rosengarten - RÖS: Georg Rösner Vertriebs GmbH - ROT: Rother Bräu - rsh: Rösslerhof - RTE: Manfred und Christine Rothe - RUH: Riensch & Held GmbH & Co. KG - RUN: Runge Nahrungsmittel GmbH - RUS: Ruschin Makrobiotik GmbH - RZO: Rzollhäusle, H.R. Hauser - SAB: SANBEAM Gesunde Produkte GmbH - SAC: Petersilchen Sanchon GmbH - säh: Karla u. Sebastian Schäfer - SAL: Salomon - SAN: Sante Naturkosmetik GmbH - SAO: Gsund & Schön Sanoll - SAR: Sanatur GmbH - SAS: S´Atra Sardigna Coop A.r.l. - SAV: Santaverde GmbH - sbä: Steinofen Bäcker - SBG: Mol Hohenlohe-Franken e.G. - SBH: Matthias Höfflin - SBM: Saarpfälzische Bio-Höfe GmbH - SCH: Naturkost Schramm GmbH - SCK: Walter Rau GmbH & Co. KG - SDE: Robert Schindele GesmbH - SDL: Siegfried Schedel - SEE: Weingut W. Seeber - SEG: Sennerei Walchsee GmbH - SEK: Sekowa Seibold KG - SEL: La Selva Vertriebs-GmbH - SFE: Hof Mühlenberg E. Schiffers - sfm: Schäfer, Martin (Michaelshof) - SFO: Sinfo Naturkost & Naturwaren - SHE: Weingut Schäfer-Heinrich - shh: Max Fischer - SIN: Singer - SJF: Sojafarm - sjh: Metzgerei Schojohann - sjs: Schaut, Josef - SKA: Schönegger Käse-Alm GmbH - SLC: Svenska LantChips AB - sle: Schilling, Erich - slm: Salm, Elvira (Limberger) - SMA: Sana-Mare - SND: Weingut Sander - SNF: Sanoflore - SNI: Weingut Stortz-Nicolaus - snn: Monika u. Thomas Sannmann - SNT: Sonett OHG - SNZ: Schnitzer Bräu - SOB: SOBO Naturkost - SÖB: Söbbeke GmbH & Co. KG - SOD: Sodasan GmbH - SOE: Salamita Soc. Coop. A.r.l. - SOF: Soto Feinkost, Oskar Schramm - SOJ: Triballat Noyal - SON: Sonne GmbH - SOT: Allgäuland - SPA: Spaichinger Nudelmacher GmbH - spe: Speckhan, Rudolf - SPH: Spreewälder Hirsemühle - SPI: Spielberger KG Naturata e.G. - SPL: Silver Plastic GmbH & Co. KG - SPR: B & G Sprossenparadies GmbH - sqn: St. Nikolaus Quelle - SRH: Scharein, Hubert - SSC: Sural-Sacicc - SSI: Santisi Vollkornnudeln - STB: Seitenbacher GmbH Naturkost - STE: Steck - sth: Scholtenhof - STN: Sonnentor GmbH - STY: Teebaumöl Kosmetik - STZ: Schnitzer OHG - SUN: Sunval Nahrungsmittel GmbH - SVA: Svadesha Naturkost- Vertrieb - SVE: Svenska Lant Chips - svm: Hof von der Mehden - SWE: Schuldt & Weber - swo: Schwollener Sprudel - sww: Karin u. Corney Weimeijer - SWZ: Schweizer GmbH - SYM: Sympakorn - tag: Tagwerk - TAI: Life Food GmbH - TAP: TAPIR Wachswaren GmbH - TAR: Tarpa Naturkost - TAU: Tautropfen GmbH - TDP: Terra di Puglia - TEL: Hakle GmbH - TER: Terrasana Naturvoeding BV - TES: Terra Soleil - TEU: Teutoburger Ölmühle - TFO: Faan Zuidhorn BV. F.Andringa - TIL: Tilouche Fruchtimport GmbH - TLI: CV Ter Linde - TMJ: Thise Mejeri - TOF: Ökofrost GmbH - TOP: ToPas GmbH - tph: T.Port Hamburg GmbH & Co. - TRA: Tradin Organic B.V. - tro: Tropenfruchtimport GmbH - TUC: Tra Terra e Cielo - ubm: Upländer Bauernmolkerei GmbH - uhe: Uta Helberg - ulh: Ulmenhof - una: Uli Natterer - uns: Unseld´s Backstube - unt: Ulrich u. Monika Unterweger - URD: Uni-Vert - URT: Urtekram A/S - VAV: Vallée-Verte Handelsges. mbH - vbr: Vollkornbäckerei Rasche - VEN: eco cosmetics GmbH & Co. KG - VGB: Bioland Schleswig Holstein - VGE: Verlag gesund essen GmbH - VGF: Hansen & Koschmieder GmbH - VIA: Viana Naturkost GmbH - VIB: Fattoria VIB - VIV: S.A. Viver, Frankreich - VIZ: Vino Zero - VLV: VivoLo Vin, Ökoweinhandel - vms: Traitteur Villemin GmbH - VNI: L. Weinrich GmbH & Co.KG - VOE: voelkel GmbH - VOL: Volvic, Frankreich - VUN: Velazquez Universal s.L. - VVE: Viola Verde GmbH - vzw: Hüser van Zwoll GmbH & Co. KG - waa: Gartenbau Waas - wal: Walter, J. - WAT: Walter Thies Zellglas - WBT: WBT SRL - WDL: Milchkoop Wendland GmbH - WDM: Windmill Organics Foods Ltd. - WDN: Großbäckerei Wendeln - web: Weber GmbH - WEG: Weingut O. Gottschalk - WEH: Peter Werth - WEL: Weleda AG - WEN: Wilhelm Weber GmbH - WER: Werz GmbH & Co. KG - WGP: Wagner Tiefkühlprodukte GmbH - who: Westhof GmbH - WHS: Deutsche Parmalat GmbH - WIE: Weingut Stephanshof - WLM: Ecover Belgium n.v. - wmr: Richard Wirthmüller - WOB: Bäckerei Wolfgruber OHG - WOL: Verlag Fred Wollner GbR - WOO: woodshade organics ApS - WPA: Wepa P. Krengel GmbH & Co. KG - WRK: Weingut Friedhelm Rinklin - WSB: Battenfeld-Spanier - wsq: Wittenseer Quelle - WTI: WTI GmbH - WUN: Wunderland e.V. - WUR: Wurzel Fachgroßhandel - WÜR: Prima Käse, Jürgen Würth - wwb: Westerwald Bio GmbH - wwi: Weber, Wilhelm - WYS: KAMO, Peter Wyssling - wzb: Wenzelburger GbR. - YAK: Faan Zuidhorn BV. F. Andringa - YAR: Yarrah Food/Vink Sales BV - ZAN: Zann Bio-Center - ZAP: Zapparoli - ZEL: Zellertaler Kellerei GmbH - ZIM: E. Zimmermann GmbH & Co - ZLN: Pastificio Zanellini spa - ZNL: Zagler´s Naturladen - zsl: Ziegenhof Schlatt - ZWE: Zwergenwiese Naturkost GmbH - ZWI: E. Zwicky (Deutschland) GmbH - ZWÖ: Weingut im Zwölberich - -category: - "01": Brot und Backwaren - "02": Milch, Milchprodukte, Eier, Tofu - "03": Obst, Gemüse, Sprossen, Pilze - "04": Fleisch, Wurst, Snacks - "05": Getreide, Ölsaaten, Nußkerne - "06": Nudeln, Trockenfrüchte, Müsli - "07": Brotaufstriche, Honig, Nußmuse - "08": Würzmittel, Öle, Fette - "09": Süßwaren, Gebäck, Pudding - "10": Spezialsortimente - "11": Tee, Kaffee, Kakao - "12": Getränke - "13": Kräuter, Heilmittel, Ätherische Öle - "14": Körperpflege und Kosmetik - "15": Wasch- und Reinigungsmittel - "16": Haushaltsgeräte - "17": Bücher und Zeitschriften - "18": Papier, Schreibwaren, Spielzeug - "19": Textilien und Schuhe - "20": Farben, Bau- u. Wohnmaterial - "0101": Brot - "0102": Brötchen, Semmeln, Brezen - "0103": Spezialitäten - "0111": Standardgebäck - "0112": Saisongebäck - "0113": Kuchen, Torten - "0121": Pikantes Gebäck - "0131": Sonstiges vom Bäcker - "0201": Milch - "0202": Sauermilchprodukte - "0203": Quark - "0204": Joghurt - "0205": Pudding - "0206": Sahne, Butter, Sonstiges - "0211": Ziegen-/Schafsmilchprodukte - "0221": Frischkäse - "0222": Weichkäse - "0223": Halbfester Schnittkäse - "0224": Schnittkäse - "0225": Hartkäse - "0231": Ziegen-/Schafskäse - "0241": Eier - "0251": Tofu, Tempeh - "0252": Soja-Frischprodukte - "0253": Soja- und Reisgetränke - "0254": Sojapudding - "0301": Obst, heimisch - "0302": Südfrüchte - "0303": Beeren - "0304": Exoten - "0311": Kartoffeln - "0312": Wurzelgemüse - "0313": Salate - "0314": Blatt- und Zwiebelgemüse - "0315": Kohlgemüse - "0316": Fruchtgemüse und Spezialitäten - "0321": Kräuter - "0331": Keime und Sprossen - "0341": Pilze - "0351": Nüsse in Schale - "0399": Div. Frischprodukte - "0401": Fleisch - "0402": Geflügel - "0411": Wurst - "0421": Fisch - "0422": Fischerzeugnisse - "0431": Burger, Kroketten - "0441": Sonstige Snacks - "0501": Getreide - "0502": Hülsenfrüchte - "0511": Ölsaaten - "0521": Nußkerne - "0531": Keimsaaten - "0601": Getreideprodukte - "0602": Flocken - "0603": Nudeln - "0611": Sojaerzeugnisse - "0621": Trockenfrüchte - "0631": Müsli - "0632": Krunchy - "0701": Würzige Aufstriche - "0702": Fruchtaufstriche - "0711": Honig - "0712": Honigprodukte - "0721": Nußmuse - "0801": Salz und Kräutersalz - "0802": Essig - "0803": Senf - "0804": Suppen und Soßen - "0805": Sojasoße und Miso - "0806": Würzmittel - "0811": Gewürze - "0812": Gewürzmischungen - "0813": Gewürzöle - "0821": Speiseöle - "0822": Margarine - "0831": Pikante Konserven - "0832": Süße Konserven - "0841": Fertiggerichte - "0842": Halbfertiggerichte - "0901": Frucht- und Knusperriegel - "0902": Bonbons und Lutscher - "0903": Schokolade - "0904": Pralinen - "0911": Dauergebäck - "0912": Waffeln - "0913": Kekse - "0914": Knabbergebäck - "0921": Süßmittel - "0922": Obstdicksäfte - "0923": Carob - "0931": Pudding - "0932": Back- und Geliermittel - "0933": Kochhilfen, Fermente - "1001": Säuglingsbreie - "1002": Babykost - "1011": Makrobiotische Spezialitäten - "1021": 3. Welt-Solidaritätswaren - "1031": Tiefkühlkost - "1051": Tiernahrung - "1101": Früchtetee - "1102": Kräutertee - "1103": Kräutertee-Mischungen - "1104": Rooibos - "1105": Gewürztee - "1111": Schwarzer Tee - "1112": Grüner Tee - "1113": Aromatisierter Tee - "1121": Bohnenkaffee - "1122": Ersatzkaffee - "1131": Kakao - "1132": Schokoladengetränke - "1201": Wasser - "1211": Fruchtsäfte - "1212": Fruchtnektare, Limonade, Schorle - "1213": Gemüsesäfte - "1215": Kwaszgetränke, Getreidegetränke, Diätgetränke - "1221": Bier - "1231": Rotwein - "1232": Rosé-Wein - "1233": Weißwein - "1241": Cidre - "1242": Schaumwein - "1251": Spirituosen - "1301": Heilkräuter - "1302": Kräutermischungen - "1311": Freiverkäufliche Arzneimittel - "1312": Kur- und Heilmittel - "1321": Ätherische Öle - "1322": Ätherische Ölmischungen - "1331": Duftlampen und Rauchgefäße - "1332": Zubehör für Duftwerk - "1341": Räucherwerk - "1401": Seife - "1402": Gesichtsreinigung und -pflege - "1403": Körperöl und Körperpflege - "1404": Haarpflege - "1405": Zahn- und Mundpflege - "1406": Handcreme - "1407": Fußpflege - "1411": Badezusätze und Duschpräparate - "1412": Deo, Eau de Toilette - "1413": Rasierzubehör - "1414": Sonnenschutz - "1415": Baby- und Kinderpflege - "1421": Dekorativkosmetik - "1422": Parfum - "1423": Sonstige Kosmetik - "1431": Zahnbürsten - "1432": Bürsten und Kämme - "1433": Kosmetikzubehör - "1441": Hygiene - "1451": Tierpflege - "1501": Waschmittel - "1502": Spülmittel - "1503": Reinigungsmittel - "1511": Dosierhilfsmittel - "1521": Schuhcreme - "1531": Insektenschutz, Düngemittel - "1601": Handmühlen - "1602": Elektromühlen - "1603": Kombi-Maschinen - "1604": Zubehör für Kombigeräte - "1611": Sonstige Haushaltsgeräte - "1612": Keimgeräte, Dörrapparate, Gärtöpfe - "1621": Küchenhelfer - "1622": Kaffee- und Teefilter - "1631": Haushaltswaren - "1701": Kochen und Backen - "1702": Ernährung und Gesundheit - "1703": Landwirtschaft und Garten - "1704": Ökologie und Ergänzendes - "1705": Baubiologie - "1706": Esoterisches - "1707": Sonstige Bücher - "1711": Zeitschriften - "1801": Schmuckpapier - "1802": Schulpapier - "1803": Neutrales Papier - "1804": Formdrucke - "1805": Geschenkpapier - "1806": Sonstiges Papier - "1811": Stifte - "1812": Malbedarf - "1813": Knetwachs - "1821": Kerzen - "1831": Spielzeug - "1832": Bastelbedarf - "1841": Edelsteine - "1851": CD's - "1852": MC's - "1901": Windeln - "1902": Baby- und Kinderwäsche - "1903": Erwachsenenwäsche - "1904": Oberbekleidung - "1905": Strümpfe - "1911": Schuhe und Einlegesohlen - "2001": Imprägnierung, Lasur, Balsame - "2002": Lacke - "2003": Wandfarben - "2004": Kleber - "2009": Sonstige Farben, Lösemittel - "2011": Tapeten - "2012": Bodenbeläge - "2013": Dämmstoffe - "2019": Sonstige Baumaterialien - "2021": Mobiliar - "2022": Matratzen - "2023": Heimtextilien - "2029": Sonstige Wohnmaterialien - "2031": Werkzeug, Hilfsmittel \ No newline at end of file diff --git a/plugins/article_import/lib/foodsoft_article_import/dnb_codes.yml b/plugins/article_import/lib/foodsoft_article_import/dnb_codes.yml deleted file mode 100644 index b7cf5b02..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/dnb_codes.yml +++ /dev/null @@ -1,129 +0,0 @@ - -# from http://www.nieuweband.nl/producten/groepen/ -indeling: - 1: Verswaren - 50: Kaas - 62: Schapenkaas - - 2: Basisproducten - 850: Noten - 855: Noten grootverbruik - 700: Peulvruchten - 705: Peulvruchten grootverbruik - 340: Rijst - 341: Rijst grootverbruik - 450: Vlokken - 455: Vlokken grootverbruik - 800: Zaden en pitten - 805: Zaden en pitten grootverbruik - 603: Melen grootverbruik - - 3: Ontbijt en lunch - 943: Marmelade - 1272: Muesli en poppies - 1000: Notenpasta - 1276: Ontbijtmelen - 1295: Rijstwafels - 1290: Roggebrood - 1270: Sandwichspread - 940: Vruchtenbeleg - 942: Vruchtenjam - 944: Vruchtenstroop - 1300: Knäckebröd, toast en beschuit - - 4: Warme maaltijd - 1820: Mosterd - 1610: Olijfolie - 1600: Olijven - 1451: Peulvruchtenconserven - 1957: Pindasaus - 1960: Sambal, ketjap en pittige smaakmakers - 2170: Seitan - 2260: Siropen - 2248: Smaakmakers - 1500: Soepen en bouillon - 1515: Soepstengels - 2000: Sojasauzen - 2250: Suiker - 1452: Tafelzuren - 1590: Tamme-kastanje-producten - 1975: Thaise keuken - 1900: Tomatenproducten - 1670: Vetten - 1930: Visconserven - 2175: Vleesvervangers - 1360: Vruchtencompote - 1400: Vruchtenconserven - 1350: Vruchtenmoes en -puree - 2249: Zout en kruidenzout - - 5: Sappen en dranken - 2605: Rode wijn Oostenrijk - 2604: Rode wijn Portugal - 2602: Rode wijn Spanje - 2608: Rode wijn Zuid-Afrika - 2612: Rosé Spanje - 2617: Rosé Zuid-Afrika - 2420: Smoothies - 2455: Sojamelkproducten - 2505: Speciaalbieren - 2400: Vruchtensappen - 2490: Waterijs - 2637: Witte wijn Argentinië - 2630: Witte wijn Frankrijk - 2634: Witte wijn Griekenland - 2631: Witte wijn Italië - 2635: Witte wijn Oostenrijk - 2632: Witte wijn Spanje - 2638: Witte wijn Zuid-Afrika - - 6: Warme dranken en theekruiden - 3102: Kruidenthee builtjes - 3100: Kruidenthee los - 3020: Kruidenthee met geneeskrachtige werking - 3009: Rooibosthee - 3010: Thee grootverpakking - 3052: Theekruiden - 3008: Witte thee - 3011: Yogi spice tea - 3012: Yogi tao tea - 3000: Zwarte thee - - 7: Versnaperingen - 3552: Lollies - 3470: Nougat en fudge - 3570: Raw Food - 3360: Rozijntjes in kinderverpakking - 3410: Snijkoek - 3555: Snoep met suiker - 3550: Snoep zonder suiker - 3405: Stroopwafels - 3350: Tortillachips en salsa - 3358: Zoete chips - 3540: Zoethoutstokjes - 3365: Zoutjes, hartige bites en popcorn - 3530: Laurierdrop - - 8: Persoonlijke verzorging en cosmetica - 5036: Lavera - 5037: Namaste - 5040: Natracare - 5042: Odylique - 5049: Sonett - 5055: Urtekram - 5065: Weleda - - 9: Natuurtherapeutisch - 5455: Kruidentincturen - 5420: Propolis-producten - 5245: Zelfzorgmiddelen - 5280: Huid- en massage-olie - - 10: Non Food - 5517: Luiers en babydoekjes - 5510: Maandverband en tampons - 5520: Toiletpapier e.d. - 5890: Voor kinderen (en volwassenen) - 5650: Was- en schoonmaakmiddelen - 5515: Watten - 5610: Luchtverfrissers diff --git a/plugins/article_import/lib/foodsoft_article_import/engine.rb b/plugins/article_import/lib/foodsoft_article_import/engine.rb deleted file mode 100644 index 49c54bab..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/engine.rb +++ /dev/null @@ -1,12 +0,0 @@ -module FoodsoftArticleImport - class Engine < ::Rails::Engine - config.to_prepare do - Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c| - require_dependency(c) - end - end - def default_foodsoft_config(cfg) - cfg[:use_article_import] = true - end - end -end diff --git a/plugins/article_import/lib/foodsoft_article_import/foodsoft.rb b/plugins/article_import/lib/foodsoft_article_import/foodsoft.rb deleted file mode 100644 index 25ff4bad..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/foodsoft.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -# Module for Foodsoft-file import -# The Foodsoft-file is a CSV-file, with semicolon-separated columns, or ODS/XLS/XLSX - -require 'roo' -require 'roo-xls' - -module FoodsoftArticleImport - module Foodsoft - NAME = 'Foodsoft (CSV, ODS, XLS, XLSX)' - OUTLIST = false - OPTIONS = { - encoding: 'UTF-8', - col_sep: ';' - }.freeze - - # Parses Foodsoft file - # the yielded article is a simple hash - def self.parse(file, custom_file_path: nil) - custom_file_path ||= nil - opts = OPTIONS.dup - - ss = FoodsoftArticleImport.open_spreadsheet(file, **opts) - - header_row = true - ss.sheet(0).each.with_index(1) do |row, i| - # skip first header row - if header_row - header_row = false - next - end - # skip empty lines - if row[2].to_s.strip.empty? - # raise no order number given - yield nil, nil, i - next - end - - article = { order_number: row[1], - name: row[2], - note: row[3], - manufacturer: row[4], - origin: row[5], - unit: row[6], - price: row[7], - tax: row[8], - unit_quantity: row[10], - article_category: row[13] } - article.merge!(deposit: row[9]) unless row[9].nil? - FoodsoftArticleImport.generate_number(article) if article[:order_number].to_s.strip.empty? - if row[6].nil? || row[7].nil? || row[8].nil? - yield article, 'Error: unit, price and tax must be entered', i - else - yield article, (row[0] == 'x' ? :outlisted : nil), i - end - end - end - end -end diff --git a/plugins/article_import/lib/foodsoft_article_import/midgard_codes.yml b/plugins/article_import/lib/foodsoft_article_import/midgard_codes.yml deleted file mode 100644 index 8777e2e7..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/midgard_codes.yml +++ /dev/null @@ -1,294 +0,0 @@ -manufacturer: - "61": Maintal - AB: Agrobioservice - AD: Anita Dehnert - AH: Phyto Treasures e.K. - AO: Arganöl - AR: ARIES - AS: Abraham Schinken - Ad: Molkerei Andechs - An: Frans Andringa - Ap: Apfeltraum - Ar: Provamel über Arche - Ay: Aytem - BA: BauckHof Amelinghausn - BB: Bakenhus Biofleisch GmbH - BC: Bio-Bäckerei Bucco - BD: Biosa - BF: Bruno Fischer - BG: Bauers Garten - BH: Bauck Hof - BHA: Bauck Hof Amelinghausen - BI: Biofarben - BK: Burger Knäcke - BKO: BioKräuterei Oberhavel - BL: Beumer & Lutum - BM: Bohlsener Mühle - BN: Brochenin - BOD: Bode Naturkost - BR: Luchs Bier - BT: Beltane Naturkost GmbH - BU: Baumschule am Butzelberg - BV: BIO VITA - BZ: Biozeit - Ba: Bauck demeter Produkte - Bb: Beutelsbacher - Bd: Biosa Danmark Aps - Be: Behncken - Bf: Backforum - Bg: Butzelberg - Bh: Barnhouse - Bj: Milchschafhof Brünjes - Bk: Blank - Bm: Biomax - Bn: Bentele - Bo: Bobalis - Bt: Bretti's - Bu: Biogärtnerei Bauer - By: Byodo - CA: Care - CF: CLUB Feinkost - CI: CIDRERIE - CV: Cosmoveda - Ca: Campo - Cl: Obsthof Clostermann - Co: Obsthof Cordes (Heinrich) - Cp: Campobello - Cs: Cosmoveda - Ct: cbet GmbH - DA: Danival - DE: DEMETER-Erzeugergemeinschaft - DH: Dieter Hein Wurstwaren - DM: Dr. Martins - DN: Hof Dannwisch - DO: Donath-Mühle - DR: De Rit - DV: Davert - DW: Vovic / Evian - De: Dennree - Dk: Dinkula - EB: Erich Boden - EH: Engemann Handel - EI: Natürlich Eistert - ELM: BIONADE - EN: Provence Regime - EO: Eosta - ER: Euresis - Eb: Eisblümerl - Eh: Erhardt Meerrettichprodukte - Ei: Eiland - El: Kelterei Elm - En: Eichhorn - Er: Erdmannhauser Brezelfabrik - Es: Erntesegen - FB: Flensburger Brauerei - FE: Frucht-Express - FF: Schiffers - FI: Fromi GmbH - FL: Florian Kerzen - FR: I Frutti del Sole - FU: Future 3000 - Fh: Florahof - Fq: Fläming-Quelle - Fr: Frunet - Ft: Fontaine - GA: Bio-Gärtnerei Altglobsow - GG: Naturhof Günter Gaßmann - GH: Gutshöfe - GN: Nesse Gewürze - GO: Der Georgshof - GS: Gut Schmerwitz - GT: Gut Temmen - Gb: Grabower - Gl: Glaciar - Go: Golden Temple - Gr: Grützdorfer - Gw: Gwidon Zastawa - Gä: Gärtnerei am Bauerngut - GÖ: Stadtgut Görlitz - HA: Haaner Felsenquelle - HB: Hof Bockum - HF: Hühnerhof Falkenthal - HK: Heinz Ketchup - HM: Hof Marienhöhe - HO: Hoffmann - HS: Obstbau H. Schalkau - Ha: Hake - Hc: Hoch Oblatenfabrik - He: Hennicke - Hk: Natur Obsthof Hauke - Hl: Heidehof - Ho: Holle - Hu: Humanopolis - Hü: Hütterman - IC: Japan Grüntee - IN: Isola della Natura - IOC: IOC - IS: Isana - Ib: Iberia - Il: Il Nuraghe - Is: ISANA - JH: Beerenobst - JS: Juers Fruchtchips - Je: Jelitta Käse - KD: Kristdyn - KG: Kräuter Gut - KK: 74271 - KN: Öko-Gartenbau - KP: Kräutergarten Pommerland - Ka: Kanne - Kg: Karg Brotgenuß - Kä: Kärrners - Kö: Obsthof König - LB: Lammsbräu - LE: LEEB Schaf- und Ziegenmolkerei - LI: Legend Organics - LM: LeMar - LS: La Selva - La: Lahmann - Lb: Lebensbaum - Le: Leuchtenberg Sauerkrautfabrik - Lh: Lindenhof - Li: Lima Belgien - Lk: Landkrone - Ln: Land in Sicht - Ls: Lubs GmbH - Lu: Luvos Heilerde - Lw: Gärtnerei Löwenzahn - MA: Mack - MB: Mabutake - ME: Martin Evers - MH: Märkische Heide - MI: Martin Ibele - MII: Katal. Olivenöl - ML: Märkisches Landbrot - MM: Bioland Imkerei - MT: Maintal - MV: MegaVega Limited - MY: Mayka Brezel - Ma: Marschland - Mg: MIDGARD - Mh: Melchhof - Mn: Mosna - Mo: Mosaikwerkstätten - My: MAYKA, Brezelfabrik - Mü: Hofmolkerei GmbH Münchehofe - MÖ: Märkischer Ökovertrieb - NE: Natürlich Eistert - NM: - NO: Nürnberger Bio Originale - NQ: Pineo Wasser - Na: NATURATA - Nt: Natumi - OTC: OTC - Od: ODIN Holland - PB: Peter Bentele - PG: Pilzgarten - PH: Biopilzhof - PM: Pinkus Müller - PN: Pro Natura - Pi: Piding - Pt: Port International - QB: Panettoncino - RB: Rother Bräu - RP: Rheinsberger Preussenquelle - RS: rosmarin BIOBACK - RZ: Ranch Zempow - Ra: Raab - Rb: Rabenhorst - Re: Rebgarten - Rg: Rosengarten - Rh: Rotenhäusler - Ro: Geflügelhof Robert - RoL: Robert´s LOSE - Rt: Rottstock - Rö: Römerquelle - SB: Sabines Bauernhof - SBP: Stiftelsen Bananen - SC: Sommer & Co. - SF: Sprossen - SH: Spreewälder Hirse - SI: SINFO - SK: Spargelhof Kreienbaum - SL: St. Leonhardsquelle - SM: Seenlan Müritz - SO: Sonett - SR: Sprossenmanufaktur GbR - STN: Sonnentor - SV: SANTAVERDE ALOE VERA - Sa: Salamita - Sb: Hans Hermann Soetbeer - Sc: Schulz-Deetz - Sch: Hof Schütte - Sd: Savid - Se: Sekem, Ägypten - Sf: Sauerkonservenfabrik Schweizer - Sh: Kombucha - Si: Land in Sicht - Sk: Schock Ludwigsburg - Sm: Schramm - So: Sophienhof - Sp: Spielberger - Sr: Sanmar - St: Steck Senf - StB: Stralsunder Brauerei - Su: Sun,Backwaren aus Norwegen - Sv: Sunval demeter-Produkte - Sw: Szilleweit - Sy: Synanon - Sz: Schrozberg - Sü: Südasien - TB: Team Blue - TF: Terra Frischdienst - TN: Tofu Nagel - TR: Teltower Rübchen - Ta: Tarpa - Te: Teutoburger Ölmühle - Ti: Tiedemann - Tm: Tillmann - Tr: tri d´Aix - Tt: Tautropfen - Tö: Töpfer Rohrzucker - UK: Udo Kolm Bananen - UL: Gärtnerei Ulenburg - UV: Uni-Vert - Ul: Ulenburg Bioland Gemüse - VA: Kleingenossenschaft VENUSTA - VD: V & D - VE: Vega e.K. - VG: Biolog. Vollwertgetränke - VT: Vogt - VV: Vallé Käse - Vi: Viana Tofu - VlV: Vivo Lo Vin - Vo: Voelkel - WB: Weber - WD: Werder Feinkost GmbH - WH: Weide-Hardebek - WK: BioCompany Kaffee - WL: Wendland Storchenmilch - WP: Plosewasser - WR: Speickwerke - WS: Weingut Sander - Wa: Watzkendorf - We: Wendts - Wh: Molkerei Weißenhorn - Wz: Werz Heidenheim - ZA: Bio-Center Zann - ZF: Obsthof zum Felde - ZG: Zwergenwiese - ZI: Biolandhof Zielke - ZK: Ziegenkäserei Karolinenhof - ZP: Bioland Ranch Zempow - ZW: Zellertaler Wein - bF: bio Frische - bi: biosanica - dB: ÖMA-d`Beers, Kisslegg im Algäu - eu: felicia - fa: familia Müsli - ha: Hawlik - vL: v.d.Linden - öG: Öko-Gartenbau - öh: ökohum Blumenerde - ÖL: Öko-Line - ÖS: Ölmühle Solling \ No newline at end of file diff --git a/plugins/article_import/lib/foodsoft_article_import/odin.rb b/plugins/article_import/lib/foodsoft_article_import/odin.rb deleted file mode 100644 index bdfa605d..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/odin.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -# Article import for De Nieuw Band XML file -# -# Always contains full assortment, including recently outlisted articles. -# To make sure we don't keep old articles when a number of updates was missed, -# +OUTLIST+ is set to +true+ to remove articles not present in the file. -# -require 'nokogiri' - -module FoodsoftArticleImport - class Odin - NAME = 'De Nieuwe Band (XML)' - OUTLIST = true - OPTIONS = {}.freeze - - # parses a string or file - def self.parse(file, custom_file_path: nil, **_opts) - custom_file_path ||= nil - xml = File.open(file) - doc = Nokogiri.XML(xml, nil, nil, - Nokogiri::XML::ParseOptions::RECOVER + - Nokogiri::XML::ParseOptions::NONET + - Nokogiri::XML::ParseOptions::COMPACT) # do not modify doc! - load_codes(custom_file_path) - doc.search('product').each.with_index(1) do |row, i| - # create a new article - unit = row.search('eenheid').text - unit = case unit.strip - when '' then 'st' - when 'stuk' then 'st' - when 'g' then 'gr' # need at least 2 chars - when 'l' then 'ltr' - else unit - end - inhoud = row.search('inhoud').text - inhoud.to_s.strip.empty? or (inhoud.to_f - 1).abs > 1e-3 and unit = inhoud.gsub(/\.0+\s*$/, '') + unit - deposit = row.search('statiegeld').text - deposit.to_s.strip.empty? and deposit = 0 - category = [ - @@codes[:indeling][row.search('indeling').text.to_i], - @@codes[:indeling][row.search('subindeling').text.to_i] - ].compact.join(' - ') - - status = row.search('status').text == 'Actief' ? nil : :outlisted - article = {} - unless row.search('bestelnummer').text == '' - article = { order_number: row.search('bestelnummer').text, - # :ean => row.search('eancode').text, - name: row.search('omschrijving').text, - note: row.search('kwaliteit').text, - manufacturer: row.search('merk').text, - origin: row.search('herkomst').text, - unit: unit, - price: row.search('prijs inkoopprijs').text, - unit_quantity: row.search('sve').text, - tax: row.search('btw').text, - deposit: deposit, - article_category: category } - end - yield article, status, i - end - end - - @@codes = {} - - def self.load_codes(custom_file_path = nil) - @gem_lib = File.expand_path '..', __dir__ - dir = File.join @gem_lib, 'foodsoft_article_import' - begin - @@codes = YAML.safe_load(File.open(File.join(dir, 'dnb_codes.yml'))).symbolize_keys - if custom_file_path - custom_codes = YAML.safe_load(File.open(custom_file_path)).symbolize_keys - custom_codes.each_key do |key| - custom_codes[key] = custom_codes[key].merge @@codes[key] if @@codes.keys.include?(key) - @@codes = @@codes.merge custom_codes - end - end - @@codes - rescue StandardError => e - raise "Failed to load dnb_codes: #{dir}/dnb_codes.yml: #{e.message}" - end - end - end -end diff --git a/plugins/article_import/lib/foodsoft_article_import/order_bnn.rb b/plugins/article_import/lib/foodsoft_article_import/order_bnn.rb deleted file mode 100644 index 59e690c1..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/order_bnn.rb +++ /dev/null @@ -1,42 +0,0 @@ -module FoodsoftArticleImport - class OrderBnn < RenderCsv - def initialize(object, options = {}) - super - @options[:col_sep] = "" - @options[:row_sep] = "\n" - @options[:encoding] = 'IBM850' - end - - def header - customer_id = "000001" - delivery_date = Time.zone.now.strftime("%y%m%d") - pickup = " " - - ["D##{customer_id}#{delivery_date}#{pickup}#{@object.id}"] - end - - def data - @object.order_articles.ordered.includes([:article, :article_price]).all.map do |oa| - yield [ - pad_to_length(oa.article.order_number, 13), - "+", - pad_float_values(oa.units_to_order), - pad_to_length(oa.article.name, 30), - pad_float_values(oa.article.unit_quantity), - pad_to_length(oa.article.unit, 14), - pad_to_length(oa.article.manufacturer, 3), - pad_to_length("", 26) - ] - end - end - - def pad_float_values(number, digits_before=4, digits_after=3) - format_string = "%0#{digits_before + digits_after}d" - formatted_number = sprintf(format_string, (number * 10 ** digits_after).to_i) - end - - def pad_to_length(string, length) - string.to_s.rjust(length, " ")[0, length] - end - end -end \ No newline at end of file diff --git a/plugins/article_import/lib/foodsoft_article_import/utf8_encoder.rb b/plugins/article_import/lib/foodsoft_article_import/utf8_encoder.rb deleted file mode 100644 index 1edb6727..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/utf8_encoder.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module UTF8Encoder - def self.clean(string) - if string.nil? - string - else - string.encode('UTF-8') - end - end -end diff --git a/plugins/article_import/lib/foodsoft_article_import/version.rb b/plugins/article_import/lib/foodsoft_article_import/version.rb deleted file mode 100644 index 5be60bf7..00000000 --- a/plugins/article_import/lib/foodsoft_article_import/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module FoodsoftArticleImport - VERSION = "0.0.1" -end diff --git a/plugins/article_import/spec/files/bnn/bnn_bad_encoding.BNN b/plugins/article_import/spec/files/bnn/bnn_bad_encoding.BNN deleted file mode 100644 index 0b7cb14e..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_bad_encoding.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -64721;A;;;4280001958081;4280001958203;Greek Dressing - Kräuter Mix;Oregano, Basilikum und Minze;;;med;;GR;C%;DE-ÖKO-001;120;1302;10;55;;1;6 x35g;6;35g;1;N;930190;99260;;1,41;;;;1;;;4,49;2,89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; -;;99 \ No newline at end of file diff --git a/plugins/article_import/spec/files/bnn/bnn_flawless.BNN b/plugins/article_import/spec/files/bnn/bnn_flawless.BNN deleted file mode 100644 index 3229196c..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_flawless.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -64721;X;;;4280001958081;4280001958203;Greek Dressing - Kr„uter Mix;Oregano, Basilikum und Minze;;;med;;GR;C%;DE-™KO-001;120;1302;10;55;;1;6 x35g;6;35g;1;N;930190;99260;;1,41;;;;1;;;4,49;2,89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; -;;99 diff --git a/plugins/article_import/spec/files/bnn/bnn_flawless_category.BNN b/plugins/article_import/spec/files/bnn/bnn_flawless_category.BNN deleted file mode 100644 index 78234d92..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_flawless_category.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -64721;A;;;4280001958081;4280001958203;Greek Dressing - Kr„uter Mix;Oregano, Basilikum und Minze;;;med;;GR;C%;DE-™KO-001;120;4000;10;55;;1;6 x35g;6;35g;1;N;930190;99260;;1,41;;;;1;;;4,49;2,89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; -;;99 diff --git a/plugins/article_import/spec/files/bnn/bnn_flawless_special.BNN b/plugins/article_import/spec/files/bnn/bnn_flawless_special.BNN deleted file mode 100644 index 0f285f6b..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_flawless_special.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -64721;A;;;4280001958081;4280001958203;Greek Dressing - Kr„uter Mix;Oregano, Basilikum und Minze;;;med;;GR;C%;DE-™KO-001;120;1302;10;55;;1;6 x35g;6;35g;1;N;930190;99260;;1,41;;;;1;;;4,49;2,89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;20230101;20230201;;Kg;28,571;; -;;99 diff --git a/plugins/article_import/spec/files/bnn/bnn_missing_entries.BNN b/plugins/article_import/spec/files/bnn/bnn_missing_entries.BNN deleted file mode 100644 index 6c8dafe9..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_missing_entries.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -64721;A;;;4280001958081;4280001958203;Greek Dressing - Kr„uter Mix;Oregano, Basilikum und Minze;;;HDE;;GR;C%;DE-™KO-001;120;1100;10;55;;1;6 x35g;6;35g;1;N;;99260;;1,41;;;;1;;;4,49;2,89;J;;;;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; -;;99 diff --git a/plugins/article_import/spec/files/bnn/bnn_missing_order_number.BNN b/plugins/article_import/spec/files/bnn/bnn_missing_order_number.BNN deleted file mode 100644 index aadcb9b6..00000000 --- a/plugins/article_import/spec/files/bnn/bnn_missing_order_number.BNN +++ /dev/null @@ -1,3 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -;A;;;4280001958081;4280001958203;Greek Dressing - Kr„uter Mix;Oregano, Basilikum und Minze;;;HDE;;GR;C%;DE-™KO-001;120;1100;10;55;;1;6 x35g;6;35g;1;N;;99260;;1,41;;;;1;;;4,49;2,89;J;;;;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; -;;99 diff --git a/plugins/article_import/spec/files/bnn/demo_file.BNN b/plugins/article_import/spec/files/bnn/demo_file.BNN deleted file mode 100644 index 3d9cc23f..00000000 --- a/plugins/article_import/spec/files/bnn/demo_file.BNN +++ /dev/null @@ -1,7 +0,0 @@ -BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 -5;;;;4280001958081;4280001958203;Žpfel Elstar;erntefrisch und knackig;;;obb;;D;C%;DE-?KO-001;120;0301;10;55;;1;10 x1kg;10;1kg;1;N;;;;1,41;;;;1;;;4,49;2,89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;1;; -6;;;;4280001958081;4280001958203;Brokkoli;gesund und lecker;;;fig;;IT;C%;DE-?KO-001;120;03;10;55;;1;6 x400g;6;400g;1;N;;;;1,41;;;;1;;;4,49;2,99;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;2,5;; -7;;;;4280001958081;4280001958203;Tomaten;pomodori italiani, demeter;;;TDP;;IT;C%;DE-?KO-001;120;03;10;55;;1;20 x500g;20;500g;1;N;;;;1,41;;;;1;;;4,49;3,19;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;2;; -8;;;;4280001958081;4280001958203;Reis;Reis im Vorratssack, demeter;;;FIN;;D;C%;DE-?KO-001;120;05;10;55;;1;12 x3k;12;3kg;1;N;;;;1,41;;;;1;;;4,49;3,49;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;0,3;; -9;;;;4280001958081;4280001958203;Spaghetti;100% italienisches Hartweizengrie?;;;ZLN;;D;C%;DE-?KO-001;120;06;10;55;;1;4 x500g;4;500g;1;N;;;;1,41;;;;1;;;4,49;2,99;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;2;; -10;;;;4280001958081;4280001958203;Kartoffeln;vorwiegend festkochend;;;rsh;;D;C%;DE-?KO-001;120;0311;10;55;;1;6 x5Kg;6;5Kg;1;N;;;;1,41;;;;1;;;4,49;3,00;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;0.2;; diff --git a/plugins/article_import/spec/files/custom_codes.yml b/plugins/article_import/spec/files/custom_codes.yml deleted file mode 100644 index 5e9020f3..00000000 --- a/plugins/article_import/spec/files/custom_codes.yml +++ /dev/null @@ -1,8 +0,0 @@ -# BNN Codes -category: - "4000": "Schuhe" -additional: - "additional": "value" -indeling: - 11: Test Indeling - 111: Test Subindeling \ No newline at end of file diff --git a/plugins/article_import/spec/files/foodsoft/foodsoft_flawless.csv b/plugins/article_import/spec/files/foodsoft/foodsoft_flawless.csv deleted file mode 100644 index a9a94c22..00000000 --- a/plugins/article_import/spec/files/foodsoft/foodsoft_flawless.csv +++ /dev/null @@ -1,3 +0,0 @@ -status;number;name;note;manufacturer;origin;unit ;clear price;tax;deposit;unit quantity;scale quantity;scale price;category -;1;product;bio;someone;eu;1 kg;1.23;6;0;10;;;coolstuff -;12;other product;bio;someone;eu;2 kg;3.45;6;0;10;;;coolstuff \ No newline at end of file diff --git a/plugins/article_import/spec/files/foodsoft/foodsoft_generate_order_number.csv b/plugins/article_import/spec/files/foodsoft/foodsoft_generate_order_number.csv deleted file mode 100644 index a50dde34..00000000 --- a/plugins/article_import/spec/files/foodsoft/foodsoft_generate_order_number.csv +++ /dev/null @@ -1,3 +0,0 @@ -status;number;name;note;manufacturer;origin;unit ;clear price;tax;deposit;unit quantity;scale quantity;scale price;category -;;product;bio;someone;eu;1 kg;1.23;6;0;10;;;coolstuff -;;other product;bio;someone;eu;2 kg;3.45;6;0;10;;;coolstuff \ No newline at end of file diff --git a/plugins/article_import/spec/files/foodsoft/foodsoft_missing_entries.csv b/plugins/article_import/spec/files/foodsoft/foodsoft_missing_entries.csv deleted file mode 100644 index 560c11af..00000000 --- a/plugins/article_import/spec/files/foodsoft/foodsoft_missing_entries.csv +++ /dev/null @@ -1,2 +0,0 @@ -status;number;name;note;manufacturer;origin;unit ;clear price;tax;deposit;unit quantity;scale quantity;scale price;category -;12;product;bio;;eu;1 kg;1.23;;0;10;;;coolstuff \ No newline at end of file diff --git a/plugins/article_import/spec/files/odin/odin_flawless.xml b/plugins/article_import/spec/files/odin/odin_flawless.xml deleted file mode 100644 index 5b5a28fc..00000000 --- a/plugins/article_import/spec/files/odin/odin_flawless.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - -1039 -1.08 -Estafette Associatie C.V. -Geldermalsen - - -8719325207668 -nucli rose -Nucli rose - -0 -0 -0 -750 -g -Stuk -0 -NELEMAN -Biologisch - - -ES - -21 -1017515 -0109 -6 -Actief -druiven* -0 -0 -2 -2 -0 -0 -0 -2 -2 -0 -2 -0 -2 -0 -2 -2 -2 -2 -1 -0 -2 -0 -2 -2 - - - -0 -0 -0 -0 -1 - -2 -0 - -adviesprijs -2022-08-18 -4.52 -7.95 - - - \ No newline at end of file diff --git a/plugins/article_import/spec/files/odin/odin_flawless_custom_category.xml b/plugins/article_import/spec/files/odin/odin_flawless_custom_category.xml deleted file mode 100644 index 460da24c..00000000 --- a/plugins/article_import/spec/files/odin/odin_flawless_custom_category.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - -1039 -1.08 -Estafette Associatie C.V. -Geldermalsen - - -8719325207668 -nucli rose -Nucli rose - -0 -0 -0 -750 -g -Stuk -0 -NELEMAN -Biologisch - - -ES - -21 -1017515 -0109 -11 -111 -6 -Actief -druiven* -0 -0 -2 -2 -0 -0 -0 -2 -2 -0 -2 -0 -2 -0 -2 -2 -2 -2 -1 -0 -2 -0 -2 -2 - - - -0 -0 -0 -0 -1 - -2 -0 - -adviesprijs -2022-08-18 -4.52 -7.95 - - - \ No newline at end of file diff --git a/plugins/article_import/spec/files/odin/odin_missing_entries.xml b/plugins/article_import/spec/files/odin/odin_missing_entries.xml deleted file mode 100644 index 5089b911..00000000 --- a/plugins/article_import/spec/files/odin/odin_missing_entries.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - -1039 -1.08 -Estafette Associatie C.V. -Geldermalsen - - -8719325207668 -nucli rose -Nucli rose - -0 -0 -0 -750 - -Stuk -0 - -Biologisch - - -ES - -21 -1017515 -0109 -6 -Non Actief -druiven* -0 -0 -2 -2 -0 -0 -0 -2 -2 -0 -2 -0 -2 -0 -2 -2 -2 -2 -1 -0 -2 -0 -2 -2 - - - -0 -0 -0 -0 -1 - -2 -0 - -adviesprijs -2022-08-18 -4.52 -7.95 - - - \ No newline at end of file diff --git a/plugins/article_import/spec/files/odin/odin_missing_order_number.xml b/plugins/article_import/spec/files/odin/odin_missing_order_number.xml deleted file mode 100644 index d43a9439..00000000 --- a/plugins/article_import/spec/files/odin/odin_missing_order_number.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - -1039 -1.08 -Estafette Associatie C.V. -Geldermalsen - - -8719325207668 -nucli rose -Nucli rose - -0 -0 -0 -750 -g -Stuk -0 -NELEMAN -Biologisch - - -ES - -21 -1017515 - -6 -Actief -druiven* -0 -0 -2 -2 -0 -0 -0 -2 -2 -0 -2 -0 -2 -0 -2 -2 -2 -2 -1 -0 -2 -0 -2 -2 - - - -0 -0 -0 -0 -1 - -2 -0 - -adviesprijs -2022-08-18 -4.52 -7.95 - - - \ No newline at end of file diff --git a/plugins/article_import/spec/lib/bnn/foodsoft_article_import_bnn_spec.rb b/plugins/article_import/spec/lib/bnn/foodsoft_article_import_bnn_spec.rb deleted file mode 100644 index d50aa591..00000000 --- a/plugins/article_import/spec/lib/bnn/foodsoft_article_import_bnn_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../../../lib/foodsoft_article_import' - -describe FoodsoftArticleImport do - files_path = File.expand_path '../../files', __dir__ - bnn_files_path = File.join(files_path, 'bnn') - - dummy_article = { name: 'Greek Dressing - Kräuter Mix', order_number: '64721', note: 'Oregano, Basilikum und Minze', - manufacturer: 'Medousa, Griechenland Importe', origin: 'GR', article_category: 'Kräutermischungen', unit: '35g', price: '2,89', tax: 7.0, unit_quantity: '6' } - - article = dummy_article.merge({ deposit: 0.08 }) - article_special = article.merge(note: 'Sonderpreis: 2,89 von 20230101 bis 20230201') - - article_2 = dummy_article.merge({ manufacturer: nil, article_category: nil }) - - article_custom_code = article.merge(article_category: 'Schuhe') - - empty = {} - - context 'bnn' do - it 'parses bnn file correctly without type parameter' do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless.BNN'))) do |new_attrs, status, _line| - expect(new_attrs).to eq article - expect(status).to eq :outlisted - end - end - it 'parses file correctly with type parameter' do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless.BNN')), type: 'bnn') do |new_attrs, status, _line| - expect(new_attrs).to eq article - expect(status).to eq :outlisted - end - end - it 'raises error wenn wrong type (except odin) specified' do - expect do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless.BNN')), type: 'foodsoft') - end.to raise_error(RuntimeError) - - expect(FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless.BNN')), type: 'odin')).to eq [] - end - it 'parses article with special correctly' do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless_special.BNN')), type: 'bnn') do |new_attrs, status, _line| - expect(new_attrs).to eq article_special - expect(status).to eq :special - end - end - it 'parses missing entries correctly' do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_missing_entries.BNN')), type: 'bnn') do |new_attrs, status, _line| - expect(new_attrs).to eq article_2 - expect(status).to eq nil - end - end - it 'skips rows without order_number' do - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_missing_order_number.BNN')), type: 'bnn') do |new_attrs, _status, _line| - expect(new_attrs).to eq empty - end - end - it 'joins custom_codes file' do - custom_file_path = File.join(files_path, 'custom_codes.yml').to_s - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_flawless_category.BNN')), custom_file_path: custom_file_path, type: 'bnn') do |new_attrs, _status, _line| - expect(new_attrs).to eq article_custom_code - end - end - it 'parses file with different encoding' do - # the bnn file is loaded with encoding ibm850. If file is not ibm850 encoded, some characters might look weird - FoodsoftArticleImport.parse(File.open(File.join(bnn_files_path, 'bnn_bad_encoding.BNN')), type: 'bnn') do |new_attrs, _status, _line| - expect(new_attrs[:order_number]).to eq('64721') - expect(new_attrs[:name]).to eq('Greek Dressing - Kräuter Mix') - end - end - end -end diff --git a/plugins/article_import/spec/lib/foodsoft/foodsoft_article_import_foodsoft_spec.rb b/plugins/article_import/spec/lib/foodsoft/foodsoft_article_import_foodsoft_spec.rb deleted file mode 100644 index 12ad16d7..00000000 --- a/plugins/article_import/spec/lib/foodsoft/foodsoft_article_import_foodsoft_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require 'foodsoft_article_import' - -describe FoodsoftArticleImport do - files_path = File.expand_path '../../files', __dir__ - foodsoft_files_path = File.join(files_path, 'foodsoft') - puts " - " + "______________" + " - " + "______________" + " - " + "______________" + " - " + "#{foodsoft_files_path}" + " - " + "______________"+ " - " + "______________"+ " - " + "______________" - - dummy_article = { order_number: '1', name: 'product', note: 'bio', manufacturer: 'someone', origin: 'eu', - unit: '1 kg', price: '1.23', tax: '6', unit_quantity: '10', article_category: 'coolstuff', deposit: '0' } - - dummy_article_2 = { order_number: '12', name: 'other product', note: 'bio', manufacturer: 'someone', - origin: 'eu', unit: '2 kg', price: '3.45', tax: '6', unit_quantity: '10', article_category: 'coolstuff', deposit: '0' } - - articles = [dummy_article, dummy_article_2] - - dummy_article_3 = dummy_article.merge({ order_number: ':d8df298' }) - dummy_article_4 = dummy_article_2.merge({ order_number: ':1f37e39' }) - articles_number_generated = [dummy_article_3, dummy_article_4] - empty = {} - - context 'foodsoft' do - it 'parses file correctly with type parameter foodsoft' do - count = 0 - FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_flawless.csv')), type: 'foodsoft') do |new_attrs, status, _line| - expect(new_attrs).to eq articles[count] - expect(status).to eq nil - count += 1 - end - end - - it 'raises error wenn wrong type specified' do - expect(FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_flawless.csv')), type: 'odin')).to eq [] - - expect(FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_flawless.csv')), type: 'bnn')).to eq [] - end - - it 'parses missing entries correctly' do - FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_missing_entries.csv')), type: 'foodsoft') do |new_attrs, status, _line| - expect(status).to eq 'Error: unit, price and tax must be entered' - expect(new_attrs[:unit]).to eq '1 kg' - expect(new_attrs[:manufacturer]).to eq nil - end - end - - it 'generates order numbers for articles without order number' do - count = 0 - FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_generate_order_number.csv')), type: 'foodsoft') do |new_attrs, _status, _line| - expect(new_attrs).to eq articles_number_generated[count] - count += 1 - end - end - - xit 'joins custom_codes file' do - custom_file_path = File.join(files_path, 'custom_codes.yml').to_s - FoodsoftArticleImport.parse(File.open(File.join(foodsoft_files_path, 'foodsoft_flawless_custom_category.csv')), custom_file_path: custom_file_path, type: 'foodsoft') do |new_attrs, _status, _line| - expect(new_attrs[:article_category]).to eq 'Test Indeling - Test Subindeling' - end - end - end -end diff --git a/plugins/article_import/spec/lib/odin/foodsoft_article_import_odin_spec.rb b/plugins/article_import/spec/lib/odin/foodsoft_article_import_odin_spec.rb deleted file mode 100644 index af3da3f4..00000000 --- a/plugins/article_import/spec/lib/odin/foodsoft_article_import_odin_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_relative '../../../lib/foodsoft_article_import' - -describe FoodsoftArticleImport do - files_path = File.expand_path '../../files', __dir__ - odin_files_path = File.join(files_path, 'odin') - - dummy_article = { order_number: '0109', name: 'nucli rose', note: 'Biologisch', manufacturer: 'NELEMAN', - origin: 'ES', unit: '750gr', price: '4.52', unit_quantity: '6', tax: '21', deposit: '0', article_category: '' } - - empty = {} - - context 'odin' do - it 'parses file correctly with type parameter odin' do - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_flawless.xml')), type: 'odin') do |new_attrs, status, _line| - expect(new_attrs).to eq dummy_article - expect(status).to eq nil - end - end - - it 'raises error wenn wrong type specified' do - expect do - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_flawless.xml')), type: 'foodsoft') - end.to raise_error(RuntimeError) - - expect do - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_flawless.xml')), type: 'bnn') - end.to raise_error(CSV::MalformedCSVError) - end - - it 'parses missing entries correctly' do - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_missing_entries.xml')), type: 'odin') do |new_attrs, status, _line| - expect(status).to eq :outlisted - expect(new_attrs[:unit]).to eq '750st' - expect(new_attrs[:manufacturer]).to eq '' - end - end - - it 'skips rows without order_number' do - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_missing_order_number.xml')), type: 'odin') do |new_attrs, _status, _line| - expect(new_attrs).to eq empty - end - end - - it 'joins custom_codes file' do - custom_file_path = File.join(files_path, 'custom_codes.yml').to_s - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'odin_flawless_custom_category.xml')), custom_file_path: custom_file_path, type: 'odin') do |new_attrs, _status, _line| - expect(new_attrs[:article_category]).to eq 'Test Indeling - Test Subindeling' - end - end - - xit 'parses dummy_article with special correctly' do - # TODO: find out whether there are special prices for odin files - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'bnn_flawless_special.BNN')), type: 'bnn') do |new_attrs, _status, _line| - expect(new_attrs.manufacturer).to eq nil - expect(new_attrs.unit).to eq '750st' - end - end - - xit 'parses file with different encoding' do - # the bnn file is loaded with encoding ibm850. If file is not ibm850 encoded, some characters might look weird - FoodsoftArticleImport.parse(File.open(File.join(odin_files_path, 'bnn_bad_encoding.BNN')), type: 'bnn') do |new_attrs, _status, _line| - expect(new_attrs[:order_number]).to eq('64721') - expect(new_attrs[:name]).to eq('Greek Dressing - Kräuter Mix') - end - end - end -end diff --git a/plugins/article_import/spec/spec_helper.rb b/plugins/article_import/spec/spec_helper.rb deleted file mode 100644 index d3e43d53..00000000 --- a/plugins/article_import/spec/spec_helper.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true - -require 'simplecov' -SimpleCov.start -# This file was generated by the `rspec --init` command. Conventionally, all -# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. -# The generated `.rspec` file contains `--require spec_helper` which will cause -# this file to always be loaded, without a need to explicitly require it in any -# files. -# -# Given that it is always loaded, you are encouraged to keep this file as -# light-weight as possible. Requiring heavyweight dependencies from this file -# will add to the boot time of your test suite on EVERY test run, even for an -# individual file that may not need all of that loaded. Instead, consider making -# a separate helper file that requires the additional dependencies and performs -# the additional setup, and require it from the spec files that actually need -# it. -# -# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration -RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended, and will default to - # `true` in RSpec 4. - mocks.verify_partial_doubles = true - end - - # This option will default to `:apply_to_host_groups` in RSpec 4 (and will - # have no way to turn it off -- the option exists only for backwards - # compatibility in RSpec 3). It causes shared context metadata to be - # inherited by the metadata hash of host groups and examples, rather than - # triggering implicit auto-inclusion in groups with matching metadata. - config.shared_context_metadata_behavior = :apply_to_host_groups - - # The settings below are suggested to provide a good initial experience - # with RSpec, but feel free to customize to your heart's content. - # # This allows you to limit a spec run to individual examples or groups - # # you care about by tagging them with `:focus` metadata. When nothing - # # is tagged with `:focus`, all examples get run. RSpec also provides - # # aliases for `it`, `describe`, and `context` that include `:focus` - # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - # config.filter_run_when_matching :focus - # - # # Allows RSpec to persist some state between runs in order to support - # # the `--only-failures` and `--next-failure` CLI options. We recommend - # # you configure your source control system to ignore this file. - # config.example_status_persistence_file_path = "spec/examples.txt" - # - # # Limits the available syntax to the non-monkey patched syntax that is - # # recommended. For more details, see: - # # https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode - # config.disable_monkey_patching! - # - # # This setting enables warnings. It's recommended, but in some cases may - # # be too noisy due to issues in dependencies. - # config.warnings = true - # - # # Many RSpec users commonly either run the entire suite or an individual - # # file, and it's useful to allow more verbose output when running an - # # individual spec file. - # if config.files_to_run.one? - # # Use the documentation formatter for detailed output, - # # unless a formatter has already been configured - # # (e.g. via a command-line flag). - # config.default_formatter = "doc" - # end - # - # # Print the 10 slowest examples and example groups at the - # # end of the spec run, to help surface which specs are running - # # particularly slow. - # config.profile_examples = 10 - # - # # Run specs in random order to surface order dependencies. If you find an - # # order dependency and want to debug it, you can fix the order by providing - # # the seed, which is printed after each run. - # # --seed 1234 - # config.order = :random - # - # # Seed global randomization in this process using the `--seed` CLI option. - # # Setting this allows you to use `--seed` to deterministically reproduce - # # test failures related to randomization by passing the same `--seed` value - # # as the one that triggered the failure. - # Kernel.srand config.seed -end