foodsoft_article_import/lib/foodsoft_article_import.rb

83 lines
3 KiB
Ruby
Raw Normal View History

2023-01-19 17:33:00 +01:00
require 'digest/sha1'
require 'tempfile'
require 'csv'
require 'yaml'
require 'active_support/core_ext/hash/keys'
require_relative 'foodsoft_article_import/bioromeo'
require_relative 'foodsoft_article_import/bnn'
2023-01-25 18:27:33 +01:00
require_relative 'foodsoft_article_import/utf8_encoder'
2023-01-19 17:33:00 +01:00
require_relative 'foodsoft_article_import/borkenstein'
require_relative 'foodsoft_article_import/dnb_xml'
require_relative 'foodsoft_article_import/foodsoft'
module FoodsoftArticleImport
class ConversionFailedException < Exception; end
# return list of known file formats
# each file_format module has
# #name return a human-readable file format name
# #outlist_unlisted if returns true, unlisted articles are outlisted
# #detect return a likelyhood (0-1) of being able to process
# #parse parse the data
#
def self.file_formats
@@file_formats ||= {
'bnn' => FoodsoftArticleImport::Bnn,
'borkenstein' => FoodsoftArticleImport::Borkenstein,
'foodsoft' => FoodsoftArticleImport::Foodsoft,
'dnb_xml' => FoodsoftArticleImport::DnbXml,
'bioromeo' => FoodsoftArticleImport::Bioromeo,
}.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
2023-01-25 18:27:33 +01:00
def self.parse(file, custom_file_path: nil, type: nil, **opts, &blk)
2023-01-19 17:33:00 +01:00
# @todo handle wrong or undetected type
2023-01-25 18:27:33 +01:00
custom_file_path ||= nil
type ||= 'bnn'
2023-01-19 17:33:00 +01:00
parser = file_formats[type]
2023-01-25 18:27:33 +01:00
puts parser
2023-01-19 17:33:00 +01:00
if block_given?
2023-01-20 15:11:23 +01:00
parser.parse(file, custom_file_path, **opts, &blk)
2023-01-19 17:33:00 +01:00
else
data = []
2023-01-20 15:11:23 +01:00
parser.parse(file, custom_file_path, **opts) { |a| data << a }
2023-01-19 17:33:00 +01:00
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
2023-01-20 15:17:52 +01:00
article[:order_number] = ':' + Digest::SHA1.hexdigest(s)[-7..-1]
2023-01-19 17:33:00 +01:00
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, filename: nil, encoding: nil, col_sep: nil)
opts = {csv_options: {}}
opts[:csv_options][:encoding] = encoding if encoding
opts[:csv_options][:col_sep] = col_sep if col_sep
opts[:extension] = File.extname(filename) if filename
2023-01-25 18:27:33 +01:00
begin
Roo::Spreadsheet.open(file, **opts)
rescue => e
raise "Failed to parse foodsoft file. make sure file format is correct: #{e.message}"
end
2023-01-19 17:33:00 +01:00
end
end