diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee index dca4e65800..ea5ab9186c 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee @@ -1,9 +1,9 @@ -angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, Enterprises, Columns) -> - Enterprises.loaded = false - $scope.allEnterprises = Enterprises.index() +angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, $q, Enterprises, Columns) -> + requests = [] + requests.push ($scope.allEnterprises = Enterprises.index(ams_suffix: "index")).$promise - $scope.loaded = -> - Enterprises.loaded + $q.all(requests).then -> + $scope.loaded = true $scope.columns = Columns.setColumns name: { name: "Name", visible: true } diff --git a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee b/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee index 357302d2b8..023f33d86c 100644 --- a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee +++ b/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee @@ -1,5 +1,5 @@ angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) -> - $resource('/admin/enterprises/:id.json', {}, { + $resource('/admin/enterprises/:id/:action.json', {}, { 'index': method: 'GET' isArray: true diff --git a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee b/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee index 3411c4a6c4..152d4ce4fb 100644 --- a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee +++ b/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee @@ -1,26 +1,21 @@ angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource) -> new class Enterprises - enterprises: [] - enterprises_by_id: {} - pristine_by_id: {} - loaded: false + enterprisesByID: {} + pristineByID: {} index: (params={}, callback=null) -> EnterpriseResource.index params, (data) => for enterprise in data - @enterprises.push enterprise - @pristine_by_id[enterprise.id] = angular.copy(enterprise) + @enterprisesByID[enterprise.id] = enterprise + @pristineByID[enterprise.id] = angular.copy(enterprise) - @loaded = true - (callback || angular.noop)(@enterprises) - - @enterprises + (callback || angular.noop)(data) save: (enterprise) -> deferred = $q.defer() enterprise.$update({id: enterprise.permalink}) .then( (data) => - @pristine_by_id[enterprise.id] = angular.copy(enterprise) + @pristineByID[enterprise.id] = angular.copy(enterprise) deferred.resolve(data) ).catch (response) -> deferred.reject(response) @@ -31,9 +26,9 @@ angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResour diff: (enterprise) -> changed = [] - for attr, value of enterprise when not angular.equals(value, @pristine_by_id[enterprise.id][attr]) + for attr, value of enterprise when not angular.equals(value, @pristineByID[enterprise.id][attr]) changed.push attr unless attr is "$$hashKey" changed resetAttribute: (enterprise, attribute) -> - enterprise[attribute] = @pristine_by_id[enterprise.id][attribute] + enterprise[attribute] = @pristineByID[enterprise.id][attribute] diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 5ccc9b9c92..73034524ff 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -25,9 +25,7 @@ module Admin def index respond_to do |format| format.html - format.json do - render json: @collection, each_serializer: Api::Admin::IndexEnterpriseSerializer, spree_current_user: spree_current_user - end + format.json { render_as_json @collection, ams_prefix: params[:ams_prefix], spree_current_user: spree_current_user } end end @@ -35,7 +33,6 @@ module Admin render layout: "spree/layouts/bare_admin" end - def update invoke_callbacks(:update, :before) if @object.update_attributes(params[object_name]) @@ -44,7 +41,7 @@ module Admin respond_with(@object) do |format| format.html { redirect_to location_after_save } format.js { render :layout => false } - format.json { render json: @object, serializer: Api::Admin::IndexEnterpriseSerializer, spree_current_user: spree_current_user } + format.json { render json: @object, ams_prefix: 'index', spree_current_user: spree_current_user } end else invoke_callbacks(:update, :fails) @@ -99,9 +96,15 @@ module Admin def for_order_cycle respond_to do |format| format.json do - render json: ActiveModel::ArraySerializer.new( @collection, - each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer, spree_current_user: spree_current_user - ).to_json + render json: @collection, each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer, spree_current_user: spree_current_user + end + end + end + + def for_line_items + respond_to do |format| + format.json do + render_as_json @collection, ams_prefix: 'basic', spree_current_user: spree_current_user end end end @@ -145,10 +148,12 @@ module Admin editable_enterprises. order('is_primary_producer ASC, name') elsif json_request? - OpenFoodNetwork::Permissions.new(spree_current_user).editable_enterprises + OpenFoodNetwork::Permissions.new(spree_current_user).editable_enterprises.ransack(params[:q]).result else - Enterprise.where("1=0") unless json_request? + Enterprise.where("1=0") end + when :for_line_items + OpenFoodNetwork::Permissions.new(spree_current_user).visible_enterprises.ransack(params[:q]).result else # TODO was ordered with is_distributor DESC as well, not sure why or how we want to sort this now OpenFoodNetwork::Permissions.new(spree_current_user). @@ -158,7 +163,7 @@ module Admin end def collection_actions - [:index, :for_order_cycle, :bulk_update] + [:index, :for_order_cycle, :for_line_items, :bulk_update] end def load_methods_and_fees @@ -248,5 +253,9 @@ module Admin main_app.edit_admin_enterprise_path(@enterprise) end end + + def ams_prefix_whitelist + [:index, :basic] + end end end diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 41b24f30a1..909f8a3567 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -12,12 +12,6 @@ module Api render params[:template] || :bulk_index end - def accessible - permitted = OpenFoodNetwork::Permissions.new(current_api_user).order_cycle_enterprises - @enterprises = permitted.ransack(params[:q]).result - render params[:template] || :bulk_index - end - def create authorize! :create, Enterprise diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb index 6ce007adf3..9888967f58 100644 --- a/app/controllers/spree/admin/base_controller_decorator.rb +++ b/app/controllers/spree/admin/base_controller_decorator.rb @@ -77,7 +77,7 @@ Spree::Admin::BaseController.class_eval do end def serializer(ams_prefix) - if ams_prefix_whitelist.include?(ams_prefix) || ams_prefix.nil? + if ams_prefix.nil? || ams_prefix_whitelist.include?(ams_prefix.to_sym) prefix = ams_prefix.andand.classify || "" name = controller_name.classify "Api::Admin::#{prefix}#{name}Serializer".constantize diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 241d1de114..abf4024fd8 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -148,7 +148,7 @@ class AbilityDecorator order.distributor.nil? || user.enterprises.include?(order.distributor) end can [:admin, :bulk_management, :managed], Spree::Order if user.admin? || user.enterprises.any?(&:is_distributor) - can [:admin, :create], Spree::LineItem + can [:admin , :for_line_items], Enterprise can [:destroy], Spree::LineItem do |item| user.admin? || user.enterprises.include?(order.distributor) || user == order.order_cycle.manager end diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml index 5f4ad6cca9..666ea4604d 100644 --- a/app/views/admin/enterprises/_enterprise_user_index.html.haml +++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml @@ -1,5 +1,5 @@ %div{ ng: { app: 'admin.enterprises', controller: 'enterprisesCtrl' } } - .row{ 'ng-hide' => '!loaded()' } + .row{ 'ng-hide' => '!loaded' } .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } .four.columns.alpha %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Search By Name' } @@ -19,15 +19,15 @@ %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} %span{ :class => 'two columns omega' } {{column.name }} - .row{ 'ng-if' => '!loaded()' } + .row{ 'ng-if' => '!loaded' } .sixteen.columns.alpha#loading %img.spinner{ src: "/assets/spinning-circles.svg" } %h1 LOADING ENTERPRISES - .row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded() && filteredEnterprises.length == 0'} + .row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded && filteredEnterprises.length == 0'} %h1#no_results No enterprises found. - .row{ ng: { show: "loaded() && filteredEnterprises.length > 0" }, bindonce: true } + .row{ ng: { show: "loaded && filteredEnterprises.length > 0" }, bindonce: true } %table.index#enterprises %col.name{ width: "28%", ng: { show: 'columns.name.visible' } } %col.producer{ width: "18%", ng: { show: 'columns.producer.visible' }} diff --git a/config/routes.rb b/config/routes.rb index 083e180212..1d26a469b9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,6 +68,7 @@ Openfoodnetwork::Application.routes.draw do resources :enterprises do collection do get :for_order_cycle + get :for_line_items post :bulk_update, as: :bulk_update end diff --git a/lib/open_food_network/permissions.rb b/lib/open_food_network/permissions.rb index 87baa533ad..2e6329bd4b 100644 --- a/lib/open_food_network/permissions.rb +++ b/lib/open_food_network/permissions.rb @@ -15,7 +15,7 @@ module OpenFoodNetwork managed_and_related_enterprises_with :add_to_order_cycle end - def order_cycle_enterprises + def visible_enterprises # Return enterprises that the user manages and those that have granted P-OC to managed enterprises managed_and_related_enterprises_granting :add_to_order_cycle end diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb index ef31b779c9..e7eabd5f82 100644 --- a/spec/controllers/admin/enterprises_controller_spec.rb +++ b/spec/controllers/admin/enterprises_controller_spec.rb @@ -515,6 +515,21 @@ module Admin end end + describe "for_line_items" do + let!(:user) { create(:user) } + let!(:enterprise) { create(:enterprise, sells: 'any', owner: user) } + + before do + # As a user with permission + controller.stub spree_current_user: user + end + + it "initializes permissions with the existing OrderCycle" do + # expect(controller).to receive(:render_as_json).with([enterprise], {ams_prefix: 'basic', spree_current_user: user}) + spree_get :for_line_items, format: :json + end + end + describe "index" do context "as super admin" do let(:super_admin) { create(:admin_user) } diff --git a/spec/controllers/spree/admin/base_controller_spec.rb b/spec/controllers/spree/admin/base_controller_spec.rb index 8619131d9f..e1b1993e8e 100644 --- a/spec/controllers/spree/admin/base_controller_spec.rb +++ b/spec/controllers/spree/admin/base_controller_spec.rb @@ -90,7 +90,7 @@ describe Spree::Admin::BaseController do before do class Api::Admin::AllowedPrefixAnonymouSerializer;end; class Api::Admin::AnonymouSerializer;end; - allow(controller).to receive(:ams_prefix_whitelist) { ['allowed_prefix'] } + allow(controller).to receive(:ams_prefix_whitelist) { [:allowed_prefix] } end context "when a prefix is passed in" do diff --git a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee index ba184045d0..ae28114ae0 100644 --- a/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee +++ b/spec/javascripts/unit/admin/enterprises/services/enterprises_spec.js.coffee @@ -4,32 +4,33 @@ describe "Enterprises service", -> beforeEach -> module 'admin.enterprises' + this.addMatchers + toDeepEqual: (expected) -> + return angular.equals(this.actual, expected) + inject ($q, _$httpBackend_, _Enterprises_, _EnterpriseResource_) -> Enterprises = _Enterprises_ EnterpriseResource = _EnterpriseResource_ $httpBackend = _$httpBackend_ - describe "#index", -> - result = null + result = response = null beforeEach -> - $httpBackend.expectGET('/admin/enterprises.json').respond 200, [{ id: 5, name: 'Enterprise 1'}] - expect(Enterprises.loaded).toBe false + response = [{ id: 5, name: 'Enterprise 1'}] + $httpBackend.expectGET('/admin/enterprises.json').respond 200, response result = Enterprises.index() $httpBackend.flush() - it "stores returned data in @enterprises, with ids as keys", -> - # This is super weird and freaking annoying. I think resource results have extra - # properties ($then, $promise) that cause them to not be equal to the reponse object - # provided to the expectGET clause above. - expect(Enterprises.enterprises).toEqual [ new EnterpriseResource({ id: 5, name: 'Enterprise 1'}) ] + it "stores returned data in @enterprisesByID, with ids as keys", -> + # EnterpriseResource returns instances of Resource rather than raw objects + expect(Enterprises.enterprisesByID).toDeepEqual { 5: response[0] } - it "returns @enterprises", -> - expect(result).toEqual Enterprises.enterprises + it "stores returned data in @pristineByID, with ids as keys", -> + expect(Enterprises.pristineByID).toDeepEqual { 5: response[0] } - it "sets @loaded to true", -> - expect(Enterprises.loaded).toBe true + it "returns an array of enterprises", -> + expect(result).toDeepEqual response describe "#save", -> @@ -40,7 +41,7 @@ describe "Enterprises service", -> resolved = false beforeEach -> - enterprise = new EnterpriseResource( { id: 15, permalink: 'enterprise1', name: 'Enterprise 1' } ) + enterprise = new EnterpriseResource({ id: 15, permalink: 'enterprise1', name: 'Enterprise 1' }) $httpBackend.expectPUT('/admin/enterprises/enterprise1.json').respond 200, { id: 15, name: 'Enterprise 1'} Enterprises.save(enterprise).then( -> resolved = true) $httpBackend.flush() @@ -48,7 +49,7 @@ describe "Enterprises service", -> it "updates the pristine copy of the enterprise", -> # Resource results have extra properties ($then, $promise) that cause them to not # be exactly equal to the response object provided to the expectPUT clause above. - expect(Enterprises.pristine_by_id[15]).toEqual enterprise + expect(Enterprises.pristineByID[15]).toEqual enterprise it "resolves the promise", -> expect(resolved).toBe(true); @@ -65,7 +66,7 @@ describe "Enterprises service", -> $httpBackend.flush() it "does not update the pristine copy of the enterprise", -> - expect(Enterprises.pristine_by_id[15]).toBeUndefined() + expect(Enterprises.pristineByID[15]).toBeUndefined() it "rejects the promise", -> expect(rejected).toBe(true); @@ -88,7 +89,7 @@ describe "Enterprises service", -> describe "diff", -> beforeEach -> - Enterprises.pristine_by_id = { 23: { id: 23, name: "ent1", is_primary_producer: true } } + Enterprises.pristineByID = { 23: { id: 23, name: "ent1", is_primary_producer: true } } it "returns a list of properties that have been altered", -> expect(Enterprises.diff({ id: 23, name: "enterprise123", is_primary_producer: true })).toEqual ["name"] @@ -98,7 +99,7 @@ describe "Enterprises service", -> enterprise = { id: 23, name: "ent1", is_primary_producer: true } beforeEach -> - Enterprises.pristine_by_id = { 23: { id: 23, name: "enterprise1", is_primary_producer: true } } + Enterprises.pristineByID = { 23: { id: 23, name: "enterprise1", is_primary_producer: true } } it "resets the specified value according to the pristine record", -> Enterprises.resetAttribute(enterprise, "name") diff --git a/spec/lib/open_food_network/permissions_spec.rb b/spec/lib/open_food_network/permissions_spec.rb index f00d8fb284..a91db5f579 100644 --- a/spec/lib/open_food_network/permissions_spec.rb +++ b/spec/lib/open_food_network/permissions_spec.rb @@ -65,7 +65,7 @@ module OpenFoodNetwork end end - describe "finding enterprises that can be added to an order cycle" do + describe "finding visible enterprises" do let(:e) { double(:enterprise) } it "returns managed and related enterprises with add_to_order_cycle permission" do @@ -73,7 +73,7 @@ module OpenFoodNetwork with(:add_to_order_cycle). and_return([e]) - expect(permissions.order_cycle_enterprises).to eq [e] + expect(permissions.visible_enterprises).to eq [e] end end