Add product category importer

This commit is contained in:
2014-09-23 16:00:31 +02:00
parent 29c908a601
commit 1f81f942f9
5 changed files with 104 additions and 0 deletions
@@ -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
@@ -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
@@ -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'
+1
View File
@@ -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
+2
View File
@@ -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
----