From 89628c27f38ba4ba5cff8df8bc41cef9e0a5892e Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Wed, 13 Nov 2019 13:51:25 +0000 Subject: [PATCH] Move exchange products endpoint to api namespace and make it work for outgoing exchanges --- .../order_cycles/services/product.js.coffee | 2 +- .../admin/exchanges_products_controller.rb | 32 ------ .../api/exchanges_products_controller.rb | 97 +++++++++++++++++++ config/routes/admin.rb | 4 - config/routes/api.rb | 4 + .../api/exchanges_products_controller_spec.rb | 36 +++++++ 6 files changed, 138 insertions(+), 37 deletions(-) delete mode 100644 app/controllers/admin/exchanges_products_controller.rb create mode 100644 app/controllers/api/exchanges_products_controller.rb create mode 100644 spec/controllers/api/exchanges_products_controller_spec.rb diff --git a/app/assets/javascripts/admin/order_cycles/services/product.js.coffee b/app/assets/javascripts/admin/order_cycles/services/product.js.coffee index cb80606609..e13e2c5069 100644 --- a/app/assets/javascripts/admin/order_cycles/services/product.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/services/product.js.coffee @@ -1,5 +1,5 @@ angular.module('admin.orderCycles').factory('Product', ($resource) -> - Product = $resource('/admin/exchanges/:exchange_id/products.json', {}, { + Product = $resource('/api/exchanges/:exchange_id/products.json', {}, { 'index': method: 'GET' isArray: true diff --git a/app/controllers/admin/exchanges_products_controller.rb b/app/controllers/admin/exchanges_products_controller.rb deleted file mode 100644 index b0d0e1b3ac..0000000000 --- a/app/controllers/admin/exchanges_products_controller.rb +++ /dev/null @@ -1,32 +0,0 @@ -module Admin - class ExchangesProductsController < Spree::Admin::BaseController - def index - @exchange = Exchange.find_by_id(params[:exchange_id]) - - respond_to do |format| - format.json do - render json: exchange_products, - each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer, - order_cycle: @exchange.order_cycle - end - end - end - - private - - # So far, products for incoming exchanges only - def exchange_products - return [] unless @exchange.incoming - - products_for_incoming_exchange - end - - def products_for_incoming_exchange - if @exchange.order_cycle.prefers_product_selection_from_coordinator_inventory_only? - @exchange.sender.supplied_products.visible_for(@order_cycle.coordinator) - else - @exchange.sender.supplied_products - end - end - end -end diff --git a/app/controllers/api/exchanges_products_controller.rb b/app/controllers/api/exchanges_products_controller.rb new file mode 100644 index 0000000000..19689030b0 --- /dev/null +++ b/app/controllers/api/exchanges_products_controller.rb @@ -0,0 +1,97 @@ +module Api + class ExchangesProductsController < Api::BaseController + skip_authorization_check only: [:index] + + def index + @exchange = Exchange.find_by_id(params[:exchange_id]) + + render json: exchange_products, + each_serializer: Api::Admin::ForOrderCycle::SuppliedProductSerializer, + order_cycle: @exchange.order_cycle, + status: :ok + end + + private + + def exchange_products + if @exchange.incoming + products_for_incoming_exchange + else + products_for_outgoing_exchange + end + end + + def products_for_incoming_exchange + supplied_products(@exchange.order_cycle, @exchange.sender) + end + + def supplied_products(order_cycle, enterprise) + if order_cycle.prefers_product_selection_from_coordinator_inventory_only? + enterprise.supplied_products.visible_for(order_cycle.coordinator) + else + enterprise.supplied_products + end + end + + def products_for_outgoing_exchange + products = [] + enterprises_for_outgoing_exchange.each do |enterprise| + products.push( *supplied_products(@exchange.order_cycle, enterprise).to_a ) + + products.each do |product| + unless product_supplied_to_order_cycle?(product) + products.delete(product) + end + end + end + products + end + + def product_supplied_to_order_cycle?(product) + (product.variants.map(&:id) & incoming_exchanges_variants).any? + end + + def incoming_exchanges_variants + return @incoming_exchanges_variants if @incoming_exchanges_variants.present? + + scoped_exchanges = + OpenFoodNetwork::OrderCyclePermissions. + new(spree_current_user, @exchange.order_cycle). + visible_exchanges. + by_enterprise_name. + incoming + + @incoming_exchanges_variants = [] + scoped_exchanges.each do |exchange| + @incoming_exchanges_variants.push( + *exchange.variants.merge(visible_incoming_variants(exchange)).map(&:id).to_a + ) + end + @incoming_exchanges_variants + end + + def visible_incoming_variants(exchange) + if exchange.order_cycle.prefers_product_selection_from_coordinator_inventory_only? + permitted_incoming_variants(exchange).visible_for(exchange.order_cycle.coordinator) + else + permitted_incoming_variants(exchange) + end + end + + def permitted_incoming_variants(exchange) + OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, exchange.order_cycle). + visible_variants_for_incoming_exchanges_from(exchange.sender) + end + + def enterprises_for_outgoing_exchange + enterprises = OpenFoodNetwork::OrderCyclePermissions. + new(spree_current_user, @exchange.order_cycle) + .visible_enterprises + return enterprises if enterprises.empty? + + enterprises.includes( + supplied_products: [:supplier, :variants, master: [:images]] + ) + end + end +end diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 310e954176..3456248e25 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -18,10 +18,6 @@ Openfoodnetwork::Application.routes.draw do end end - resources :exchanges do - resources :products, controller: 'exchanges_products' - end - resources :enterprises do collection do get :for_order_cycle diff --git a/config/routes/api.rb b/config/routes/api.rb index 34f80b7b13..50c12a9e0c 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -43,6 +43,10 @@ Openfoodnetwork::Application.routes.draw do get :properties, on: :member end + resources :exchanges do + resources :products, controller: 'exchanges_products' + end + resource :status do get :job_queue end diff --git a/spec/controllers/api/exchanges_products_controller_spec.rb b/spec/controllers/api/exchanges_products_controller_spec.rb new file mode 100644 index 0000000000..8648aadfc0 --- /dev/null +++ b/spec/controllers/api/exchanges_products_controller_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +module Api + describe ExchangesProductsController, type: :controller do + include AuthenticationWorkflow + + let!(:order_cycle) { create(:order_cycle) } + let!(:coordinator) { order_cycle.coordinator } + + before do + allow(controller).to receive_messages spree_current_user: coordinator.owner + end + + describe "#index" do + describe "for incoming exchanges" do + it "loads data" do + exchange = order_cycle.exchanges.incoming.first + spree_get :index, exchange_id: exchange.id + + expect(json_response.first["supplier_name"]).to eq exchange.variants.first.product.supplier.name + end + end + + describe "for outgoing exchanges" do + it "loads data" do + exchange = order_cycle.exchanges.outgoing.first + spree_get :index, exchange_id: exchange.id + + suppliers = [exchange.variants[0].product.supplier.name, exchange.variants[1].product.supplier.name] + expect(suppliers).to include json_response.first["supplier_name"] + expect(suppliers).to include json_response.second["supplier_name"] + end + end + end + end +end