I want to add a new 'vendor' role. A vendor can manage his own products and orders, but not see any orders or products belonging to an other vendor.
I was planning to implement this around the Stock Location. E.g: One user with the vendor role belongs to the Tokyo stock location. An other user with the vendor role belongs to an other stock location.
Which steps need to me taken to get this working?
$ rails console
Spree::Role.create(name: 'vendor')
app/models/spree/multi_vendor_ability.rb
module Spree
class MultiVendorAbility
include CanCan::Ability
def initialize(user)
user ||= Spree::User.new # guest user (not logged in)
if user.admin?
can :manage, :all
puts "IS admin"
else
can :read, :all
puts "NOT admin"
end
if user.stock_locations.present?
can :manage, Spree::StockItem, :stock_location_id => user.stock_locations.first.id
end
end
end
end
config/initializers/spree_user.rb
Spree::User.class_eval do
def vendor?
self.role_users.any? { |ru| ru.role.name == 'vendor' }
end
end
spec/models/multi_vendor_spec.rb
require 'spec_helper'
describe Spree::MultiVendorAbility do
let(:ability) { Spree::MultiVendorAbility.new(user) }
let(:user) { create(:user) }
let(:product) { create :product }
let(:stock_location) { create(:stock_location_with_items) }
let(:stock_item) { stock_location.stock_items.order(:id).first }
subject { ability }
context "test" do
before do
Rails.logger.debug "The StockItem is #{stock_item.inspect}"
user.stock_locations = [stock_location]
user.save
end
context "when the user is associated with the stock location" do
it { is_expected.to be_able_to(:manage, Spree::StockItem) }
end
context "when the user is NOT associated with the stock location" do
before do
stock_item.stock_location_id = nil
stock_item.save
user.stock_locations = []
user.save
puts "The StockItem is #{stock_item.inspect}"
user.stock_locations = []
end
it { is_expected.to_not be_able_to(:manage, Spree::StockItem) }
end
end
end