Add product category importer
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user