include foodsoft-article-import
use filetypes for manual uploading bnn, odin, foodsoft file use opts in .parse adapt specs to include file format add specs for odin, bnn, foodsoft files adapt localize input to remove ',' separator and replace with '.' remove depr foodsoftfile.rb and spreadsheet.rb remove todo
This commit is contained in:
parent
936c1ba878
commit
4b5775e107
15 changed files with 492 additions and 120 deletions
|
|
@ -148,11 +148,12 @@ class ArticlesController < ApplicationController
|
|||
# Update articles from a spreadsheet
|
||||
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, options
|
||||
@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
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
# Foodsoft-file import
|
||||
class FoodsoftFile
|
||||
# parses a string from a foodsoft-file
|
||||
# returns two arrays with articles and outlisted_articles
|
||||
# the parsed article is a simple hash
|
||||
def self.parse(file, options = {})
|
||||
SpreadsheetFile.parse file, options do |row, row_index|
|
||||
next if row[2].blank?
|
||||
|
||||
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],
|
||||
:deposit => (row[9].nil? ? "0" : row[9]),
|
||||
:unit_quantity => row[10],
|
||||
:article_category => row[13] }
|
||||
status = row[0] && row[0].strip.downcase == 'x' ? :outlisted : nil
|
||||
yield status, article, row_index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
require 'roo'
|
||||
|
||||
class SpreadsheetFile
|
||||
def self.parse(file, options = {})
|
||||
filepath = file.is_a?(String) ? file : file.to_path
|
||||
filename = options.delete(:filename) || filepath
|
||||
fileext = File.extname(filename)
|
||||
options[:csv_options] = { col_sep: ';', encoding: 'utf-8' }.merge(options[:csv_options] || {})
|
||||
s = Roo::Spreadsheet.open(filepath, options.merge({ extension: fileext }))
|
||||
|
||||
row_index = 1
|
||||
s.each do |row|
|
||||
if row_index == 1
|
||||
# @todo try to detect headers; for now using the index is ok
|
||||
else
|
||||
yield row, row_index
|
||||
end
|
||||
row_index += 1
|
||||
end
|
||||
row_index
|
||||
end
|
||||
end
|
||||
|
|
@ -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, ".") # Replace separator with db compatible character
|
||||
input.gsub!(separator, ".") or input.gsub!(",", ".") # Replace separator with db compatible character
|
||||
input
|
||||
rescue
|
||||
Rails.logger.warn "Can't localize input: #{input}"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
require 'foodsoft_article_import'
|
||||
class Supplier < ApplicationRecord
|
||||
include MarkAsDeletedWithName
|
||||
include CustomFields
|
||||
|
|
@ -73,13 +74,16 @@ class Supplier < ApplicationRecord
|
|||
# Synchronise articles with spreadsheet.
|
||||
#
|
||||
# @param file [File] Spreadsheet file to parse
|
||||
# @param options [Hash] Options passed to {FoodsoftFile#parse} except when listed here.
|
||||
# @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, options = {})
|
||||
def sync_from_file(file, type, options = {})
|
||||
all_order_numbers = []
|
||||
updated_article_pairs, outlisted_articles, new_articles = [], [], []
|
||||
FoodsoftFile::parse file, options do |status, new_attrs, line|
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -71,9 +71,14 @@
|
|||
= form_for :articles, :url => parse_upload_supplier_articles_path(@supplier),
|
||||
:html => { multipart: true, class: "form-horizontal" } do |f|
|
||||
|
||||
|
||||
.control-group
|
||||
%label(for="articles_file")= t '.file_label'
|
||||
%label(for="articles_file")
|
||||
%strong= t '.file_label'
|
||||
= f.file_field "file"
|
||||
%label(for="articles_file")
|
||||
%strong="select the file type you are about to upload"
|
||||
=f.collection_select :type, ["bnn","foodsoft","odin"], :to_s, :to_s
|
||||
|
||||
.control-group
|
||||
%label(for="articles_update_category")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue