WIP: BOM Refactor, adding for_line_items action to enterprises controller

This commit is contained in:
Rob Harrington
2015-11-04 15:02:29 +11:00
parent 625e0888ea
commit ae7e744644
14 changed files with 79 additions and 64 deletions

View File

@@ -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 }

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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' }}

View File

@@ -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

View File

@@ -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

View File

@@ -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) }

View File

@@ -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

View File

@@ -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")

View File

@@ -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