mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-18 04:39:14 +00:00
Merge pull request #4101 from luisramos0/remove_variants_rabl
Convert spree/api/products and spree/api/variants views from rabl to AMS
This commit is contained in:
124
app/controllers/api/products_controller.rb
Normal file
124
app/controllers/api/products_controller.rb
Normal file
@@ -0,0 +1,124 @@
|
||||
require 'open_food_network/permissions'
|
||||
|
||||
module Api
|
||||
class ProductsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:show, :bulk_products, :overridable]
|
||||
|
||||
def show
|
||||
@product = find_product(params[:id])
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Product
|
||||
params[:product][:available_on] ||= Time.zone.now
|
||||
@product = Spree::Product.new(params[:product])
|
||||
begin
|
||||
if @product.save
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: 201
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
@product.permalink = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
if @product.update_attributes(params[:product])
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: 200
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Product
|
||||
@product = find_product(params[:id])
|
||||
@product.update_attribute(:deleted_at, Time.zone.now)
|
||||
@product.variants_including_master.update_all(deleted_at: Time.zone.now)
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: 204
|
||||
end
|
||||
|
||||
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
|
||||
def bulk_products
|
||||
@products = OpenFoodNetwork::Permissions.new(current_api_user).editable_products.
|
||||
merge(product_scope).
|
||||
order('created_at DESC').
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def overridable
|
||||
producers = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
variant_override_producers.by_name
|
||||
|
||||
@products = paged_products_for_producers producers
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def soft_delete
|
||||
authorize! :delete, Spree::Product
|
||||
@product = find_product(params[:product_id])
|
||||
authorize! :delete, @product
|
||||
@product.destroy
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: 204
|
||||
end
|
||||
|
||||
# POST /api/products/:product_id/clone
|
||||
#
|
||||
def clone
|
||||
authorize! :create, Spree::Product
|
||||
original_product = find_product(params[:product_id])
|
||||
authorize! :update, original_product
|
||||
|
||||
@product = original_product.duplicate
|
||||
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: 201
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Copied and modified from SpreeApi::BaseController to allow
|
||||
# enterprise users to access inactive products
|
||||
def product_scope
|
||||
# This line modified
|
||||
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
|
||||
scope = Spree::Product
|
||||
if params[:show_deleted]
|
||||
scope = scope.with_deleted
|
||||
end
|
||||
else
|
||||
scope = Spree::Product.active
|
||||
end
|
||||
|
||||
scope.includes(:master)
|
||||
end
|
||||
|
||||
def paged_products_for_producers(producers)
|
||||
Spree::Product.scoped.
|
||||
merge(product_scope).
|
||||
where(supplier_id: producers).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
def render_paged_products(products)
|
||||
serializer = ActiveModel::ArraySerializer.new(
|
||||
products,
|
||||
each_serializer: Api::Admin::ProductSerializer
|
||||
)
|
||||
|
||||
render text: { products: serializer, pages: products.num_pages }.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
79
app/controllers/api/variants_controller.rb
Normal file
79
app/controllers/api/variants_controller.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
module Api
|
||||
class VariantsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
skip_authorization_check only: [:index, :show]
|
||||
before_filter :product
|
||||
|
||||
def index
|
||||
@variants = scope.includes(:option_values).ransack(params[:q]).result
|
||||
render json: @variants, each_serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.includes(:option_values).find(params[:id])
|
||||
render json: @variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Spree::Variant
|
||||
@variant = scope.new(params[:variant])
|
||||
if @variant.save
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: 201
|
||||
else
|
||||
invalid_resource!(@variant)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
if @variant.update_attributes(params[:variant])
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: 200
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def soft_delete
|
||||
@variant = scope.find(params[:variant_id])
|
||||
authorize! :delete, @variant
|
||||
|
||||
VariantDeleter.new.delete(@variant)
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: 204
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Spree::Variant
|
||||
@variant = scope.find(params[:id])
|
||||
@variant.destroy
|
||||
render json: @variant, serializer: Api::VariantSerializer, status: 204
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product
|
||||
@product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id]
|
||||
end
|
||||
|
||||
def scope
|
||||
if @product
|
||||
unless current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
variants = @product.variants_including_master
|
||||
else
|
||||
variants = @product.variants_including_master.with_deleted
|
||||
end
|
||||
else
|
||||
variants = Spree::Variant.scoped
|
||||
if current_api_user.has_spree_role?("admin")
|
||||
unless params[:show_deleted]
|
||||
variants = Spree::Variant.active
|
||||
end
|
||||
else
|
||||
variants = variants.active
|
||||
end
|
||||
end
|
||||
variants
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,149 +0,0 @@
|
||||
require 'open_food_network/permissions'
|
||||
|
||||
module Spree
|
||||
module Api
|
||||
class ProductsController < Spree::Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
if params[:ids]
|
||||
@products = product_scope.where(id: params[:ids])
|
||||
else
|
||||
@products = product_scope.ransack(params[:q]).result
|
||||
end
|
||||
|
||||
@products = @products.page(params[:page]).per(params[:per_page])
|
||||
|
||||
respond_with(@products)
|
||||
end
|
||||
|
||||
def show
|
||||
@product = find_product(params[:id])
|
||||
respond_with(@product)
|
||||
end
|
||||
|
||||
def new; end
|
||||
|
||||
def create
|
||||
authorize! :create, Product
|
||||
params[:product][:available_on] ||= Time.zone.now
|
||||
@product = Product.new(params[:product])
|
||||
begin
|
||||
if @product.save
|
||||
respond_with(@product, status: 201, default_template: :show)
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
@product.permalink = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Product
|
||||
@product = find_product(params[:id])
|
||||
if @product.update_attributes(params[:product])
|
||||
respond_with(@product, status: 200, default_template: :show)
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Product
|
||||
@product = find_product(params[:id])
|
||||
@product.update_attribute(:deleted_at, Time.zone.now)
|
||||
@product.variants_including_master.update_all(deleted_at: Time.zone.now)
|
||||
respond_with(@product, status: 204)
|
||||
end
|
||||
|
||||
def managed
|
||||
authorize! :admin, Spree::Product
|
||||
authorize! :read, Spree::Product
|
||||
|
||||
@products = product_scope.
|
||||
ransack(params[:q]).result.
|
||||
managed_by(current_api_user).
|
||||
page(params[:page]).per(params[:per_page])
|
||||
respond_with(@products, default_template: :index)
|
||||
end
|
||||
|
||||
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
|
||||
def bulk_products
|
||||
@products = OpenFoodNetwork::Permissions.new(current_api_user).editable_products.
|
||||
merge(product_scope).
|
||||
order('created_at DESC').
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def overridable
|
||||
producers = OpenFoodNetwork::Permissions.new(current_api_user).
|
||||
variant_override_producers.by_name
|
||||
|
||||
@products = paged_products_for_producers producers
|
||||
|
||||
render_paged_products @products
|
||||
end
|
||||
|
||||
def soft_delete
|
||||
authorize! :delete, Spree::Product
|
||||
@product = find_product(params[:product_id])
|
||||
authorize! :delete, @product
|
||||
@product.destroy
|
||||
respond_with(@product, status: 204)
|
||||
end
|
||||
|
||||
# POST /api/products/:product_id/clone
|
||||
#
|
||||
def clone
|
||||
authorize! :create, Spree::Product
|
||||
original_product = find_product(params[:product_id])
|
||||
authorize! :update, original_product
|
||||
|
||||
@product = original_product.duplicate
|
||||
|
||||
respond_with(@product, status: 201, default_template: :show)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Copied and modified from Spree::Api::BaseController to allow
|
||||
# enterprise users to access inactive products
|
||||
def product_scope
|
||||
# This line modified
|
||||
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
|
||||
scope = Spree::Product
|
||||
if params[:show_deleted]
|
||||
scope = scope.with_deleted
|
||||
end
|
||||
else
|
||||
scope = Spree::Product.active
|
||||
end
|
||||
|
||||
scope.includes(:master)
|
||||
end
|
||||
|
||||
def paged_products_for_producers(producers)
|
||||
Spree::Product.scoped.
|
||||
merge(product_scope).
|
||||
where(supplier_id: producers).
|
||||
by_producer.by_name.
|
||||
ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
end
|
||||
|
||||
def render_paged_products(products)
|
||||
serializer = ActiveModel::ArraySerializer.new(
|
||||
products,
|
||||
each_serializer: ::Api::Admin::ProductSerializer
|
||||
)
|
||||
|
||||
render text: { products: serializer, pages: products.num_pages }.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,83 +0,0 @@
|
||||
module Spree
|
||||
module Api
|
||||
class VariantsController < Spree::Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
before_filter :product
|
||||
|
||||
def index
|
||||
@variants = scope.includes(:option_values).ransack(params[:q]).result.
|
||||
page(params[:page]).per(params[:per_page])
|
||||
respond_with(@variants)
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.includes(:option_values).find(params[:id])
|
||||
respond_with(@variant)
|
||||
end
|
||||
|
||||
def new; end
|
||||
|
||||
def create
|
||||
authorize! :create, Variant
|
||||
@variant = scope.new(params[:variant])
|
||||
if @variant.save
|
||||
respond_with(@variant, status: 201, default_template: :show)
|
||||
else
|
||||
invalid_resource!(@variant)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Variant
|
||||
@variant = scope.find(params[:id])
|
||||
if @variant.update_attributes(params[:variant])
|
||||
respond_with(@variant, status: 200, default_template: :show)
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
end
|
||||
|
||||
def soft_delete
|
||||
@variant = scope.find(params[:variant_id])
|
||||
authorize! :delete, @variant
|
||||
|
||||
VariantDeleter.new.delete(@variant)
|
||||
respond_with @variant, status: 204
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Variant
|
||||
@variant = scope.find(params[:id])
|
||||
@variant.destroy
|
||||
respond_with(@variant, status: 204)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product
|
||||
@product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id]
|
||||
end
|
||||
|
||||
def scope
|
||||
if @product
|
||||
unless current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
variants = @product.variants_including_master
|
||||
else
|
||||
variants = @product.variants_including_master.with_deleted
|
||||
end
|
||||
else
|
||||
variants = Variant.scoped
|
||||
if current_api_user.has_spree_role?("admin")
|
||||
unless params[:show_deleted]
|
||||
variants = Variant.active
|
||||
end
|
||||
else
|
||||
variants = variants.active
|
||||
end
|
||||
end
|
||||
variants
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,6 +4,12 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
def check_price
|
||||
if currency.nil?
|
||||
self.currency = Spree::Config[:currency]
|
||||
end
|
||||
end
|
||||
|
||||
def refresh_products_cache
|
||||
variant.andand.refresh_products_cache
|
||||
end
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
class Api::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :is_master, :on_hand, :name_to_display, :unit_to_display, :unit_value
|
||||
attributes :options_text, :on_demand, :price, :fees, :price_with_fees, :product_name
|
||||
attributes :id, :is_master, :product_name, :sku
|
||||
attributes :options_text, :unit_value, :unit_description, :unit_to_display
|
||||
attributes :display_as, :display_name, :name_to_display
|
||||
attributes :price, :on_demand, :on_hand, :fees, :price_with_fees
|
||||
attributes :tag_list
|
||||
|
||||
delegate :price, to: :object
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
object @enterprise
|
||||
|
||||
attributes :id, :name
|
||||
@@ -1,2 +0,0 @@
|
||||
collection @products.order('id ASC')
|
||||
extends "spree/api/products/bulk_show"
|
||||
@@ -1,27 +0,0 @@
|
||||
object @product
|
||||
|
||||
# TODO: This is used by bulk product edit when a product is cloned.
|
||||
# But the list of products is serialized by Api::Admin::ProductSerializer.
|
||||
# This should probably be unified.
|
||||
|
||||
attributes :id, :name, :sku, :variant_unit, :variant_unit_scale, :variant_unit_name, :on_demand, :inherits_properties
|
||||
attributes :on_hand, :price, :available_on, :permalink_live, :tax_category_id
|
||||
|
||||
# Infinity is not a valid JSON object, but Rails encodes it anyway
|
||||
node( :taxon_ids ) { |p| p.taxons.map(&:id).join(",") }
|
||||
node( :on_hand ) { |p| p.on_hand.nil? ? 0 : p.on_hand.to_f.finite? ? p.on_hand : t(:on_demand) }
|
||||
node( :price ) { |p| p.price.nil? ? '0.0' : p.price }
|
||||
|
||||
node( :available_on ) { |p| p.available_on.blank? ? "" : p.available_on.strftime("%F %T") }
|
||||
node( :permalink_live, &:permalink )
|
||||
node( :producer_id, &:supplier_id )
|
||||
node( :category_id, &:primary_taxon_id )
|
||||
node( :supplier ) do |p|
|
||||
partial 'api/enterprises/bulk_show', object: p.supplier
|
||||
end
|
||||
node( :variants ) do |p|
|
||||
partial 'spree/api/variants/bulk_index', object: p.variants.reorder('spree_variants.id ASC')
|
||||
end
|
||||
node( :master ) do |p|
|
||||
partial 'spree/api/variants/bulk_show', object: p.master
|
||||
end
|
||||
@@ -1,2 +0,0 @@
|
||||
collection @variants
|
||||
extends "spree/api/variants/bulk_show"
|
||||
@@ -1,7 +0,0 @@
|
||||
object @variant
|
||||
|
||||
attributes :id, :options_text, :unit_value, :unit_description, :on_demand, :display_as, :display_name
|
||||
|
||||
# Infinity is not a valid JSON object, but Rails encodes it anyway
|
||||
node( :on_hand ) { |v| v.on_hand.nil? ? 0 : ( v.on_hand.to_f.finite? ? v.on_hand : t(:on_demand) ) }
|
||||
node( :price ) { |v| v.price.nil? ? 0.to_f : v.price }
|
||||
Reference in New Issue
Block a user