From 12adfe4289f502e304d8f116fd3c29d09df6e1af Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 20 Feb 2023 19:56:45 +0100 Subject: [PATCH 1/4] update article category implemented --- app/controllers/articles_controller.rb | 1 + app/models/article.rb | 32 +++++++++++++----------- app/models/supplier.rb | 9 +++++-- app/views/articles/_sync_table.html.haml | 3 ++- app/views/articles/upload.html.haml | 3 +++ 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 4161e66a..a3ae0676 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -151,6 +151,7 @@ class ArticlesController < ApplicationController 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 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') diff --git a/app/models/article.rb b/app/models/article.rb index 76a68605..e329b49d 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -142,21 +142,25 @@ class Article < ApplicationRecord new_unit_quantity = new_article.unit_quantity new_unit = new_article.unit end + if options[:update_category] == true + new_article_category = new_article.article_category + end - return Article.compare_attributes( - { - :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] - } - ) + 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] + } + attribute_hash[:article_category] = [self.article_category, new_article_category] if new_article_category + + Article.compare_attributes(attribute_hash) end # Compare attributes from two different articles. diff --git a/app/models/supplier.rb b/app/models/supplier.rb index 862f5c24..6daab986 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -81,7 +81,12 @@ class Supplier < ApplicationRecord 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]) + + + unless new_attrs[:article_category].blank? + new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) ? ArticleCategory.find_match(new_attrs[:article_category]) : ArticleCategory.create_or_find_by!(name: new_attrs[:article_category]) + end + new_attrs[:tax] ||= FoodsoftConfig[:tax_default] new_article = articles.build(new_attrs) @@ -89,7 +94,7 @@ class Supplier < ApplicationRecord if article.nil? new_articles << new_article else - unequal_attributes = article.unequal_attributes(new_article, options.slice(:convert_units)) + 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] diff --git a/app/views/articles/_sync_table.html.haml b/app/views/articles/_sync_table.html.haml index ac17adfa..62640cbe 100644 --- a/app/views/articles/_sync_table.html.haml +++ b/app/views/articles/_sync_table.html.haml @@ -49,7 +49,8 @@ .input-prepend %span.add-on= t 'number.currency.format.unit' = 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{:style => highlight_new(attrs, :article_category)} + = 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 diff --git a/app/views/articles/upload.html.haml b/app/views/articles/upload.html.haml index 8f91d790..7695d28b 100644 --- a/app/views/articles/upload.html.haml +++ b/app/views/articles/upload.html.haml @@ -76,6 +76,9 @@ = f.file_field "file" .control-group + %label(for="articles_update_category") + = f.check_box "update_category" + = "update category ?" %label(for="articles_outlist_absent") = f.check_box "outlist_absent" = t '.options.outlist_absent' From 346e985c49ee2670b865709506a40d81d108a51b Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 20 Feb 2023 21:34:29 +0100 Subject: [PATCH 2/4] adapt tests --- spec/integration/articles_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/integration/articles_spec.rb b/spec/integration/articles_spec.rb index bbd5e375..84a27cd4 100644 --- a/spec/integration/articles_spec.rb +++ b/spec/integration/articles_spec.rb @@ -80,11 +80,13 @@ feature ArticlesController do describe "handles missing data" do it do find('input[type="submit"]').click # to overview + element = find('#new_articles__price') + element.fill_in with: "" 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 + element.fill_in with: 5.56 find('input[type="submit"]').click # now it should succeed expect(supplier.articles.count).to eq 1 end From da1015abd1adeda3f17597ec0c05c5f48ce55b87 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Thu, 23 Feb 2023 13:28:36 +0100 Subject: [PATCH 3/4] add translations, adapt test and fix bug --- app/controllers/articles_controller.rb | 10 ++++----- app/models/article.rb | 8 +++---- app/models/supplier.rb | 9 ++++---- app/views/articles/upload.html.haml | 2 +- config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/nl.yml | 1 + spec/integration/articles_spec.rb | 29 +++++++++++++++++++++++--- 9 files changed, 45 insertions(+), 17 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index a3ae0676..31481f18 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -46,6 +46,11 @@ class ArticlesController < ApplicationController render :layout => false end + def edit + @article = Article.find(params[:id]) + render :action => 'new', :layout => false + end + def create @article = Article.new(params[:article]) if @article.valid? && @article.save @@ -55,11 +60,6 @@ class ArticlesController < ApplicationController end end - def edit - @article = Article.find(params[:id]) - render :action => 'new', :layout => false - end - # Updates one Article and highlights the line if succeded def update @article = Article.find(params[:id]) diff --git a/app/models/article.rb b/app/models/article.rb index e329b49d..1eca49cd 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -142,9 +142,6 @@ class Article < ApplicationRecord new_unit_quantity = new_article.unit_quantity new_unit = new_article.unit end - if options[:update_category] == true - new_article_category = new_article.article_category - end attribute_hash = { :name => [self.name, new_article.name], @@ -158,7 +155,10 @@ class Article < ApplicationRecord :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] } - attribute_hash[:article_category] = [self.article_category, new_article_category] if new_article_category + 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 diff --git a/app/models/supplier.rb b/app/models/supplier.rb index 6daab986..a4a7456e 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -82,9 +82,10 @@ class Supplier < ApplicationRecord FoodsoftFile::parse file, options do |status, new_attrs, line| article = articles.undeleted.where(order_number: new_attrs[:order_number]).first - - unless new_attrs[:article_category].blank? - new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) ? ArticleCategory.find_match(new_attrs[:article_category]) : ArticleCategory.create_or_find_by!(name: new_attrs[:article_category]) + 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] @@ -94,7 +95,7 @@ class Supplier < ApplicationRecord if article.nil? new_articles << new_article else - unequal_attributes = article.unequal_attributes(new_article, options.slice(:convert_units,:update_category)) + 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] diff --git a/app/views/articles/upload.html.haml b/app/views/articles/upload.html.haml index 7695d28b..221e0d1a 100644 --- a/app/views/articles/upload.html.haml +++ b/app/views/articles/upload.html.haml @@ -78,7 +78,7 @@ .control-group %label(for="articles_update_category") = f.check_box "update_category" - = "update category ?" + = t '.options.update_category' %label(for="articles_outlist_absent") = f.check_box "outlist_absent" = t '.options.outlist_absent' diff --git a/config/locales/de.yml b/config/locales/de.yml index 5a1a5b35..3e4e54d5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -568,6 +568,7 @@ de: options: convert_units: Derzeitige Einheiten beibehalten, berechne Mengeneinheit und Preis (wie Synchronisieren). outlist_absent: Artikel löschen, die nicht in der hochgeladenen Datei sind. + update_category: Kategorien aus der Datei übernehmen und erstellen. sample: juices: Säfte nuts: Nüsse diff --git a/config/locales/en.yml b/config/locales/en.yml index 59e94385..39053a82 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -569,6 +569,7 @@ en: options: convert_units: Keep current units, recompute unit quantity and price (like synchronize). outlist_absent: Delete articles not in uploaded file. + update_category: Create and replace categories from uploaded file. sample: juices: Juices nuts: Nuts diff --git a/config/locales/es.yml b/config/locales/es.yml index 620ec3bb..6363c9d3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -515,6 +515,7 @@ es: options: convert_units: Mantener unidades actuales, recomputar la cantidad y precio de unidades (como sincronizar). outlist_absent: Borrar artículos que no están en el archivo subido. + update_category: Toma las categorías del archivo subido. sample: juices: Jugos nuts: Nueces diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 4c97dda4..1af1e65d 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -539,6 +539,7 @@ nl: options: convert_units: Bestaande eenheden behouden, herbereken groothandelseenheid en prijs (net als synchronizeren). outlist_absent: Artikelen die niet in het bestand voorkomen, verwijderen. + upload_category: Categorieën overnemen uit bestand. sample: juices: Sappen nuts: Noten diff --git a/spec/integration/articles_spec.rb b/spec/integration/articles_spec.rb index 84a27cd4..1967a617 100644 --- a/spec/integration/articles_spec.rb +++ b/spec/integration/articles_spec.rb @@ -80,18 +80,41 @@ feature ArticlesController do describe "handles missing data" do it do find('input[type="submit"]').click # to overview - element = find('#new_articles__price') - element.fill_in with: "" find('input[type="submit"]').click # missing category, re-show form expect(find('tr.alert')).to be_present expect(supplier.articles.count).to eq 0 - element.fill_in with: 5.56 + 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 "takes over category from file" do + it do + find(:css, '#articles_update_category[value="1"]').set(true) # check take over category from file + expect(ArticleCategory.count).to eq 1 # new Category vegetables should be created from file + find('input[type="submit"]').click # upload file + find('input[type="submit"]').click # submit changes + expect(ArticleCategory.count).to eq 2 # it is + expect(supplier.articles.count).to eq 1 + expect(supplier.articles.first.article_category.name).to eq "Vegetables" + end + end + + describe "overwrites article_category from file" do + let!(:article_category) { create(:article_category, name: "Fruit") } + let(:article) { create(:article, supplier: supplier, name: 'Tomatoes', order_number: 1, unit: '250 g', article_category: article_category) } + + it do + find(:css, '#articles_update_category[value="1"]').set(true) # check take over category from file + find('input[type="submit"]').click #upload file + find('input[type="submit"]').click #submit changes + expect(supplier.articles.count).to eq 1 + expect(supplier.articles.first.article_category.name).to eq "Vegetables" + end + end + describe "can remove an existing article" do let!(:article) { create :article, supplier: supplier, name: 'Foobar', order_number: 99999 } From 44f5d139201673d66a3eecfb7fbf0a74f5a142d7 Mon Sep 17 00:00:00 2001 From: viehlieb Date: Mon, 20 Feb 2023 19:56:45 +0100 Subject: [PATCH 4/4] update article category implemented adapt tests add translations adapt test fix bug --- app/controllers/articles_controller.rb | 11 ++++---- app/models/article.rb | 32 +++++++++++++----------- app/models/supplier.rb | 10 ++++++-- app/views/articles/_sync_table.html.haml | 3 ++- app/views/articles/upload.html.haml | 3 +++ config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/nl.yml | 1 + spec/integration/articles_spec.rb | 25 ++++++++++++++++++ 10 files changed, 66 insertions(+), 22 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 4161e66a..31481f18 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -46,6 +46,11 @@ class ArticlesController < ApplicationController render :layout => false end + def edit + @article = Article.find(params[:id]) + render :action => 'new', :layout => false + end + def create @article = Article.new(params[:article]) if @article.valid? && @article.save @@ -55,11 +60,6 @@ class ArticlesController < ApplicationController end end - def edit - @article = Article.find(params[:id]) - render :action => 'new', :layout => false - end - # Updates one Article and highlights the line if succeded def update @article = Article.find(params[:id]) @@ -151,6 +151,7 @@ class ArticlesController < ApplicationController 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 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') diff --git a/app/models/article.rb b/app/models/article.rb index 76a68605..1eca49cd 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -143,20 +143,24 @@ class Article < ApplicationRecord new_unit = new_article.unit end - return Article.compare_attributes( - { - :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] - } - ) + 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 # Compare attributes from two different articles. diff --git a/app/models/supplier.rb b/app/models/supplier.rb index 862f5c24..a4a7456e 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -81,7 +81,13 @@ class Supplier < ApplicationRecord 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]) + + 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) @@ -89,7 +95,7 @@ class Supplier < ApplicationRecord if article.nil? new_articles << new_article else - unequal_attributes = article.unequal_attributes(new_article, options.slice(:convert_units)) + 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] diff --git a/app/views/articles/_sync_table.html.haml b/app/views/articles/_sync_table.html.haml index ac17adfa..62640cbe 100644 --- a/app/views/articles/_sync_table.html.haml +++ b/app/views/articles/_sync_table.html.haml @@ -49,7 +49,8 @@ .input-prepend %span.add-on= t 'number.currency.format.unit' = 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{:style => highlight_new(attrs, :article_category)} + = 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 diff --git a/app/views/articles/upload.html.haml b/app/views/articles/upload.html.haml index 8f91d790..221e0d1a 100644 --- a/app/views/articles/upload.html.haml +++ b/app/views/articles/upload.html.haml @@ -76,6 +76,9 @@ = f.file_field "file" .control-group + %label(for="articles_update_category") + = f.check_box "update_category" + = t '.options.update_category' %label(for="articles_outlist_absent") = f.check_box "outlist_absent" = t '.options.outlist_absent' diff --git a/config/locales/de.yml b/config/locales/de.yml index 5a1a5b35..3e4e54d5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -568,6 +568,7 @@ de: options: convert_units: Derzeitige Einheiten beibehalten, berechne Mengeneinheit und Preis (wie Synchronisieren). outlist_absent: Artikel löschen, die nicht in der hochgeladenen Datei sind. + update_category: Kategorien aus der Datei übernehmen und erstellen. sample: juices: Säfte nuts: Nüsse diff --git a/config/locales/en.yml b/config/locales/en.yml index 59e94385..39053a82 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -569,6 +569,7 @@ en: options: convert_units: Keep current units, recompute unit quantity and price (like synchronize). outlist_absent: Delete articles not in uploaded file. + update_category: Create and replace categories from uploaded file. sample: juices: Juices nuts: Nuts diff --git a/config/locales/es.yml b/config/locales/es.yml index 620ec3bb..6363c9d3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -515,6 +515,7 @@ es: options: convert_units: Mantener unidades actuales, recomputar la cantidad y precio de unidades (como sincronizar). outlist_absent: Borrar artículos que no están en el archivo subido. + update_category: Toma las categorías del archivo subido. sample: juices: Jugos nuts: Nueces diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 4c97dda4..1af1e65d 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -539,6 +539,7 @@ nl: options: convert_units: Bestaande eenheden behouden, herbereken groothandelseenheid en prijs (net als synchronizeren). outlist_absent: Artikelen die niet in het bestand voorkomen, verwijderen. + upload_category: Categorieën overnemen uit bestand. sample: juices: Sappen nuts: Noten diff --git a/spec/integration/articles_spec.rb b/spec/integration/articles_spec.rb index bbd5e375..1967a617 100644 --- a/spec/integration/articles_spec.rb +++ b/spec/integration/articles_spec.rb @@ -90,6 +90,31 @@ feature ArticlesController do end end + describe "takes over category from file" do + it do + find(:css, '#articles_update_category[value="1"]').set(true) # check take over category from file + expect(ArticleCategory.count).to eq 1 # new Category vegetables should be created from file + find('input[type="submit"]').click # upload file + find('input[type="submit"]').click # submit changes + expect(ArticleCategory.count).to eq 2 # it is + expect(supplier.articles.count).to eq 1 + expect(supplier.articles.first.article_category.name).to eq "Vegetables" + end + end + + describe "overwrites article_category from file" do + let!(:article_category) { create(:article_category, name: "Fruit") } + let(:article) { create(:article, supplier: supplier, name: 'Tomatoes', order_number: 1, unit: '250 g', article_category: article_category) } + + it do + find(:css, '#articles_update_category[value="1"]').set(true) # check take over category from file + find('input[type="submit"]').click #upload file + find('input[type="submit"]').click #submit changes + expect(supplier.articles.count).to eq 1 + expect(supplier.articles.first.article_category.name).to eq "Vegetables" + end + end + describe "can remove an existing article" do let!(:article) { create :article, supplier: supplier, name: 'Foobar', order_number: 99999 }