Handle errors in upload and sync form

This commit is contained in:
wvengen 2015-04-03 15:53:08 +02:00
parent 18cc105c1e
commit 6ce1b7f928
6 changed files with 61 additions and 38 deletions

View file

@ -160,48 +160,40 @@ class ArticlesController < ApplicationController
if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty? if @updated_article_pairs.empty? && @outlisted_articles.empty? && @new_articles.empty?
redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.sync.notice') redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.sync.notice')
end end
@ignored_article_count = @supplier.articles.where(order_number: [nil, '']).count
end end
# Updates, deletes articles when upload or sync form is submitted # Updates, deletes articles when upload or sync form is submitted
def update_synchronized def update_synchronized
begin @outlisted_articles = Article.find(params[:outlisted_articles].try(:keys)||[])
Article.transaction do @updated_articles = Article.find(params[:articles].try(:keys)||[])
# delete articles @updated_articles.map{|a| a.assign_attributes(params[:articles][a.id.to_s]) }
if params[:outlisted_articles] @new_articles = (params[:new_articles]||[]).map{|a| @supplier.articles.build(a) }
Article.find(params[:outlisted_articles].keys).each(&:mark_as_deleted)
end
# Update articles has_error = false
if params[:articles] Article.transaction do
params[:articles].each do |id, attrs| # delete articles
Article.find(id).update_attributes! attrs @outlisted_articles.each(&:mark_as_deleted)
end # Update articles
end @updated_articles.map{|a| a.save or has_error=true }
# Add new articles
# Add new articles @new_articles.each do |article|
if params[:new_articles] article.availability = true if @supplier.shared_sync_method == 'all_available'
params[:new_articles].each do |attrs| article.availability = false if @supplier.shared_sync_method == 'all_unavailable'
article = Article.new attrs article.save or has_error=true
article.supplier = @supplier
article.availability = true if @supplier.shared_sync_method == 'all_available'
article.availability = false if @supplier.shared_sync_method == 'all_unavailable'
article.save!
end
end
end end
# Successfully done. raise ActiveRecord::Rollback if has_error
end
if !has_error
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice') redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
else
rescue ActiveRecord::RecordInvalid => invalid @updated_article_pairs = @updated_articles.map do |article|
# An error has occurred, transaction has been rolled back. orig_article = Article.find(article.id)
redirect_to supplier_articles_path(@supplier), [article, orig_article.unequal_attributes(article)]
alert: I18n.t('articles.controller.error_update', :article => invalid.record.name, :msg => invalid.record.errors.full_messages) end
flash.now.alert = I18n.t('articles.controller.error_invalid')
rescue => error render params[:from_action] == 'sync' ? :sync : :parse_upload
redirect_to supplier_articles_path(@supplier),
alert: I18n.t('errors.general_msg', :msg => error.message)
end end
end end
@ -227,4 +219,16 @@ class ArticlesController < ApplicationController
render :action => 'new', :layout => false render :action => 'new', :layout => false
end end
end end
private
# @return [Number] Number of articles not taken into account when syncing (having no number)
helper_method \
def ignored_article_count
if action_name == 'sync' || params[:from_action] == 'sync'
@ignored_article_count ||= @supplier.articles.where(order_number: [nil, '']).count
else
0
end
end
end end

View file

@ -27,6 +27,6 @@
= render 'sync_table', articles: @new_articles, field: 'new_articles', hidden_fields: %w(shared_updated_on order_number) = render 'sync_table', articles: @new_articles, field: 'new_articles', hidden_fields: %w(shared_updated_on order_number)
%hr/ %hr/
- if @ignored_article_count > 0 - if ignored_article_count > 0
%p %p
%i= t '.outlist.body_ignored', count: @ignored_article_count %i= t '.outlist.body_ignored', count: ignored_article_count

View file

@ -51,3 +51,6 @@
= form.text_field 'deposit', class: 'input-mini', style: 'width: 45px' = form.text_field 'deposit', class: 'input-mini', style: 'width: 45px'
%td= form.select :article_category_id, ArticleCategory.all.map {|a| [ a.name, a.id ] }, %td= form.select :article_category_id, ArticleCategory.all.map {|a| [ a.name, a.id ] },
{include_blank: true}, class: 'input-small' {include_blank: true}, class: 'input-small'
- unless changed_article.errors.empty?
%tr.alert
%td(colspan=11)= changed_article.errors.full_messages.join(', ')

View file

@ -1,6 +1,7 @@
- title t('.title', supplier: @supplier.name) - title t('.title', supplier: @supplier.name)
= form_tag update_synchronized_supplier_articles_path(@supplier) do = form_tag update_synchronized_supplier_articles_path(@supplier) do
= hidden_field_tag :from_action, 'parse_upload'
= render 'sync' = render 'sync'
.form-actions .form-actions
= submit_tag t('.submit'), class: 'btn btn-primary' = submit_tag t('.submit'), class: 'btn btn-primary'

View file

@ -1,6 +1,8 @@
- title t('.title') - title t('.title')
= form_tag update_synchronized_supplier_articles_path(@supplier) do = form_tag update_synchronized_supplier_articles_path(@supplier) do
= hidden_field_tag :from_action, 'sync'
= render 'sync' = render 'sync'
= submit_tag t('.submit'), class: 'btn btn-primary' .form-actions
= link_to t('ui.or_cancel'), supplier_articles_path(@supplier) = submit_tag t('.submit'), class: 'btn btn-primary'
= link_to t('ui.or_cancel'), supplier_articles_path(@supplier)

View file

@ -72,6 +72,19 @@ describe ArticlesController, :type => :feature do
end end
end end
describe "handles missing data" do
it do
find('input[type="submit"]').click # to overview
find('input[type="submit"]').click # missing category, re-show form
expect(find('tr.alert')).to be_present
expect(supplier.articles.count).to eq 0
all("tr select > option")[1].select_option
find('input[type="submit"]').click # now it should succeed
expect(supplier.articles.count).to eq 1
end
end
#describe "can remove an existing article" do #describe "can remove an existing article" do
# let!(:article) { create :article, supplier: supplier, name: 'Foobar', order_number: 99999 } # let!(:article) { create :article, supplier: supplier, name: 'Foobar', order_number: 99999 }
# it do # it do