diff --git a/app/controllers/suppliers/product_categories_controller.rb b/app/controllers/suppliers/product_categories_controller.rb index 785ae422..b9d97ef8 100644 --- a/app/controllers/suppliers/product_categories_controller.rb +++ b/app/controllers/suppliers/product_categories_controller.rb @@ -9,6 +9,22 @@ module Suppliers respond_to do |format| format.html # index.html.erb format.json { render json: @product_categories } + format.yaml do + @product_categories.include_relation(:products) + h = {product_categories: []} + @product_categories.each do |product_category| + h[:product_categories] << { + name: product_category.name, + products: product_category.products.map{|product| { + name: product.name, + price: product.price, + code: product.code, + description: product.description + }} + } + end + render text: h.deep_stringify_keys.to_yaml + end end end @@ -39,6 +55,18 @@ module Suppliers @product_category = ProductCategory.find(params[:id]) end + def import + redirect_to({action: :index}, alert: 'no_file_given') and return unless params[:file].present? + result = ProductCategoriesImporter.new(current_supplier).import(params[:file].read) + if result.errors.any? + redirect_to({action: :index}, alert: result.errors.message) + else + redirect_to action: :index + end + rescue => e + redirect_to({action: :index}, alert: 'something went wrong') + end + # POST /product_categories # POST /product_categories.json def create diff --git a/app/services/product_categories_importer.rb b/app/services/product_categories_importer.rb new file mode 100644 index 00000000..8e7771c4 --- /dev/null +++ b/app/services/product_categories_importer.rb @@ -0,0 +1,68 @@ +class ProductCategoriesImporter + attr_reader :errors, :supplier, :skipped + + def initialize(supplier) + @errors = Errors.new + @errors.importer = self + @supplier = supplier + end + + def import(string) + h = YAML.load(string) rescue nil + return errors.add 'cannot_parse_yaml' unless h + return errors.add 'no_product_categories' unless h["product_categories"].is_a?(Array) + categories = supplier.product_categories + existing_products = supplier.products + @skipped = [] + h["product_categories"].each do |product_category_spec| + skipped << {reason: 'empty_name', type: 'product_category'} and next unless product_category_spec['name'].present? + unless existing_category = categories.find{|pc| pc.name == product_category_spec['name']} + existing_category = ProductCategory.new + product_category_spec.each do |attribute, value| + existing_category.public_send "#{attribute}=", value if existing_category.respond_to? "#{attribute}=" + end + end + existing_category.supplier = supplier # hard coded security + if existing_category.valid? + (product_category_spec['products'] || []).each do |product_spec| + skipped << {reason: 'empty_name', type: 'product'} and next unless product_spec['name'].present? + + unless existing_product = existing_products.find{|ep| ep.name == product_spec['name']} + existing_product = Product.new + end + product_spec.each do |product_attribute, product_value| + existing_product.public_send "#{product_attribute}=", product_value if existing_product.respond_to? "#{product_attribute}=" + end + + existing_product.supplier = supplier + if existing_product.save + existing_category.product_ids |= [existing_product.id] + else + skipped << {reason: 'could_not_save', type: 'product'} + end + + end + existing_category.save + else + skipped << {reason: 'could_not_save', type: 'product_category'} + end + end + self + end + + def success? + errors.empty? + end + + class Errors < Hash + attr_accessor :importer + def add(message) + self[:message] = message + importer + end + + def message + self[:message] + end + end +end diff --git a/app/views/suppliers/product_categories/index.html.slim b/app/views/suppliers/product_categories/index.html.slim index d9da4ed6..686665c4 100644 --- a/app/views/suppliers/product_categories/index.html.slim +++ b/app/views/suppliers/product_categories/index.html.slim @@ -16,3 +16,8 @@ - else = no_content_given model_class = supplier_form_actions :new, for: :product_categories + +.import.panel.hide + = form_tag import_suppliers_product_categories_path, multipart: true do + = file_field_tag :file + = submit_tag 'import' diff --git a/config/routes.rb b/config/routes.rb index a9914edc..c9cd3df2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -137,6 +137,7 @@ Qwaiter::Application.routes.draw do resources :product_categories do collection do post :sort + post :import end end resources :orders, only: [:index, :show] do diff --git a/wip.md b/wip.md index c5d52320..ee2d188a 100644 --- a/wip.md +++ b/wip.md @@ -7,6 +7,8 @@ Supplier - english emails - form action button looks (Roos) - Add qr print functionality offering to send the stickers +- Limit tables to section +- Add qr-print button to tables User ----