From d5a7f6a07465434666da992a60db85f11be52124 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 27 Mar 2015 19:03:21 +0100 Subject: [PATCH] Move file import logic to model --- app/controllers/articles_controller.rb | 25 ++------------- app/models/supplier.rb | 43 +++++++++++++++++++++++--- config/locales/en.yml | 6 ++-- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index f3d5177b..512dd531 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -139,28 +139,9 @@ class ArticlesController < ApplicationController def parse_upload uploaded_file = params[:articles]['file'] options = {filename: uploaded_file.original_filename} - # @todo move parsing to model (concern) - @updated_article_pairs, @outlisted_articles, @new_articles = [], [], [] - FoodsoftFile::parse uploaded_file.tempfile, options do |status, new_attrs, line| - article = @supplier.articles.where(order_number: new_attrs[:order_number]).first - new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) - new_attrs[:tax] ||= FoodsoftConfig[:tax_default] - new_article = @supplier.articles.build(new_attrs) - - if status.nil? && article.nil? - @new_articles << new_article - elsif status.nil? && article.present? - unequal_attributes = article.unequal_attributes(new_article) - article.attributes = unequal_attributes - @updated_article_pairs << [article, unequal_attributes] - elsif status == :outlisted && article.present? - @outlisted_articles << article - - # stop when there is a parsing error - elsif status.is_a? String - raise I18n.t('articles.controller.error_parse', :msg => status, :line => line.to_s) - end - + @updated_article_pairs, @outlisted_articles, @new_articles = @supplier.sync_from_file uploaded_file.tempfile, 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 diff --git a/app/models/supplier.rb b/app/models/supplier.rb index e792835b..fa87dfb7 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -26,9 +26,7 @@ class Supplier < ActiveRecord::Base # also returns an array with outlisted_articles, which should be deleted # also returns an array with new articles, which should be added (depending on shared_sync_method) def sync_all - updated_articles = Array.new - outlisted_articles = Array.new - new_articles = Array.new + updated_article_pairs, outlisted_articles, new_articles = [], [], [] for article in articles.undeleted # try to find the associated shared_article shared_article = article.shared_article(self) @@ -37,7 +35,7 @@ class Supplier < ActiveRecord::Base unequal_attributes = article.shared_article_changed?(self) unless unequal_attributes.blank? # skip if shared_article has not been changed article.attributes = unequal_attributes - updated_articles << [article, unequal_attributes] + updated_article_pairs << [article, unequal_attributes] end # Articles with no order number can be used to put non-shared articles # in a shared supplier, with sync keeping them. @@ -54,7 +52,42 @@ class Supplier < ActiveRecord::Base end end end - return [updated_articles, outlisted_articles, new_articles] + return [updated_article_pairs, outlisted_articles, new_articles] + end + + # Synchronise articles with spreadsheet. + # + # @param file [File] Spreadsheet file to parse + # @param options [Hash] Options passed to {FoodsoftFile#parse} except when listed here. + # @option options [Boolean] :outlist_absent Set to +true+ to remove articles not in spreadsheet. + def sync_from_file(file, options={}) + updated_article_pairs, outlisted_articles, new_articles = [], [], [] + FoodsoftFile::parse file, options do |status, new_attrs, line| + article = articles.undeleted.where(order_number: new_attrs[:order_number]).first + new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) + 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) + 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 + end + return [updated_article_pairs, outlisted_articles, new_articles] end # default value diff --git a/config/locales/en.yml b/config/locales/en.yml index 46028e6f..6a691fe2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -355,12 +355,11 @@ en: notice: "%{count} new articles were saved." error_invalid: There are errors in articles error_nosel: No articles selected - error_parse: "%{msg} ... in line %{line}" error_update: 'An error occured when updating article ''%{article}'': %{msg}' parse_upload: - notice: "%{count} articles were succesfully analysed." + notice: Articles are already up to date. sync: - notice: Catalog is up to date + notice: Articles are already up to date. shared_alert: "%{supplier} is not linked to an external database" update_all: notice: All articles and prices were updated. @@ -405,6 +404,7 @@ en: model: error_in_use: "%{article} can not be deleted because the article is part of a current order!" error_nosel: You have selected no articles + error_parse: "%{msg} ... in line %{line}" parse_upload: body: "

Please verify the articles.

Warning, at the moment there is no check for duplicate articles.

" submit: Process upload