Merge branch 'master' of github.com:eaterprises/openfoodweb

This commit is contained in:
alexs
2013-08-12 17:35:36 +10:00
24 changed files with 188 additions and 53 deletions

View File

@@ -2,6 +2,8 @@ module Admin
class EnterpriseFeesController < ResourceController
before_filter :load_enterprise_fee_set, :only => :index
before_filter :load_data
before_filter :do_not_destroy_referenced_fees, :only => :destroy
def index
respond_to do |format|
@@ -21,6 +23,20 @@ module Admin
private
def do_not_destroy_referenced_fees
product_distribution = ProductDistribution.where(:enterprise_fee_id => @object).first
if product_distribution
p = product_distribution.product
flash[:error] = "That enterprise fee cannot be deleted as it is referenced by a product distribution: #{p.id} - #{p.name}."
respond_with(@object) do |format|
format.html { redirect_to collection_url }
format.js { render text: flash[:error], status: 403 }
end
end
end
def load_enterprise_fee_set
@enterprise_fee_set = EnterpriseFeeSet.new :collection => collection
end
@@ -32,6 +48,5 @@ module Admin
def collection
super.order('enterprise_id', 'fee_type', 'name')
end
end
end

View File

@@ -0,0 +1,8 @@
Spree::Admin::Orders::CustomerDetailsController.class_eval do
#Override BaseController.authorize_admin to inherit CanCan permissions for the current order
def authorize_admin
load_order unless @order
authorize! :admin, @order
authorize! params[:action].to_sym, @order
end
end

View File

@@ -1,6 +1,12 @@
# When a user fires an event, take them back to where they came from
# Responder: http://guides.spreecommerce.com/developer/logic.html#overriding-controller-action-responses
# For some strange reason, adding PaymentsController.class_eval will cause gems/spree/app/controllers/spree/admin/payments_controller.rb:37 to error:
# payments_url not defined.
# This could be fixed by replacing line 37 with:
# respond_with(@payment, location: admin_order_payments_url) { |format| format.html { redirect_to admin_order_payments_path(@order) } }
Spree::Admin::PaymentsController.class_eval do
respond_override :fire => { :html => { :success => lambda {
redirect_to request.referer # Keeps any filter and sort prefs

View File

@@ -0,0 +1,4 @@
class AdjustmentMetadata < ActiveRecord::Base
belongs_to :adjustment, class_name: 'Spree::Adjustment'
belongs_to :enterprise
end

View File

@@ -9,4 +9,7 @@ class EnterpriseFee < ActiveRecord::Base
validates_inclusion_of :fee_type, :in => FEE_TYPES
validates_presence_of :name
scope :for_enterprise, lambda { |enterprise| where(enterprise_id: enterprise) }
end

View File

@@ -5,7 +5,7 @@ class ProductDistribution < ActiveRecord::Base
belongs_to :enterprise_fee
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_presence_of :distributor_id, :enterprise_fee_id
validates_uniqueness_of :product_id, :scope => :distributor_id
@@ -25,7 +25,8 @@ class ProductDistribution < ActiveRecord::Base
end
def create_adjustment_for(line_item)
enterprise_fee.create_adjustment(adjustment_label_for(line_item), line_item.order, line_item, true)
a = enterprise_fee.create_adjustment(adjustment_label_for(line_item), line_item.order, line_item, true)
AdjustmentMetadata.create! adjustment: a, enterprise: enterprise_fee.enterprise, fee_name: enterprise_fee.name, fee_type: enterprise_fee.fee_type, enterprise_role: 'distributor'
end
def clear_all_enterprise_fee_adjustments_for(line_item)

View File

@@ -19,13 +19,14 @@ class AbilityDecorator
#User can only access orders that they are a distributor for
can [:index, :create], Spree::Order
can [:admin, :read, :update, :fire, :resend ], Spree::Order do |order| # :customer, :return_authorizations
can [:admin, :read, :update, :fire, :resend ], Spree::Order do |order|
user.enterprises.include? order.distributor
end
can [:admin, :index, :read, :create, :edit], Spree::Payment # , :fire, :capture,
can [:admin, :index, :read, :create, :edit], Spree::Shipment #edit order shipment doesn't work
can [:admin, :index, :read, :create, :edit], Spree::Adjustment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
end
end

View File

@@ -1,5 +1,7 @@
module Spree
Adjustment.class_eval do
has_one :metadata, class_name: 'AdjustmentMetadata'
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
end
end

View File

@@ -1,5 +1,7 @@
-# copied from backend/app/views/spree/admin/payments/_list.html.erb
- # Get the payment in 'checkout' state if any, and show capture button
- if order.payments.present?
- order.payments.last.actions.grep(/^capture$/).each do |action|
= link_to_with_icon "icon-#{action}", t(action), fire_admin_order_payment_path(order, order.payments.last, :e => action), :method => :put, :no_text => true, :data => {:action => action}
- payment = order.payments.select{|p| p if p.state == 'checkout'}.first
- if !payment.nil?
- payment.actions.grep(/^capture$/).each do |action|
- # copied from backend/app/views/spree/admin/payments/_list.html.erb
= link_to_with_icon "icon-#{action}", t(action), fire_admin_order_payment_path(order, payment, :e => action), :method => :put, :no_text => true, :data => {:action => action}

View File

@@ -11,4 +11,4 @@
= label_tag "#{pd_form.object_name}[_destroy]", pd_form.object.distributor.name
= pd_form.hidden_field :distributor_id
%td
= pd_form.collection_select :shipping_method_id, Spree::ShippingMethod.all, :id, :name, {}, :class => "select2"
= pd_form.collection_select :enterprise_fee_id, EnterpriseFee.for_enterprise(pd_form.object.distributor), :id, :name, {}, :class => "select2"

View File

@@ -0,0 +1,19 @@
class CreateEnterpriseFeeRecordsForProductDistributions < ActiveRecord::Migration
def up
ProductDistribution.all.each do |pd|
calculator = pd.shipping_method.calculator.dup
calculator.save!
ef = EnterpriseFee.new enterprise_id: pd.distributor.id, fee_type: 'packing', name: pd.shipping_method.name
ef.calculator = calculator
ef.save!
pd.enterprise_fee = ef
pd.save!
end
end
def down
ProductDistribution.update_all :enterprise_fee_id => nil
end
end

View File

@@ -0,0 +1,13 @@
class CreateAdjustmentMetadata < ActiveRecord::Migration
def change
create_table :adjustment_metadata do |t|
t.integer :adjustment_id
t.integer :enterprise_id
t.string :fee_name
t.string :fee_type
t.string :enterprise_role
end
add_index :adjustment_metadata, :adjustment_id
end
end

View File

@@ -11,7 +11,17 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130807230834) do
ActiveRecord::Schema.define(:version => 20130809075103) do
create_table "adjustment_metadata", :force => true do |t|
t.integer "adjustment_id"
t.integer "enterprise_id"
t.string "fee_name"
t.string "fee_type"
t.string "enterprise_role"
end
add_index "adjustment_metadata", ["adjustment_id"], :name => "index_adjustment_metadata_on_adjustment_id"
create_table "carts", :force => true do |t|
t.integer "user_id"

View File

@@ -77,9 +77,10 @@ FactoryGirl.define do
end
factory :enterprise_fee, :class => EnterpriseFee do
sequence(:name) { |n| "Enterprise fee #{n}" }
enterprise { Enterprise.first || FactoryGirl.create(:supplier_enterprise) }
fee_type 'packing'
name '$0.50 / kg'
calculator { FactoryGirl.build(:weight_calculator) }
after(:create) { |ef| ef.calculator.save! }
@@ -88,7 +89,6 @@ FactoryGirl.define do
factory :product_distribution, :class => ProductDistribution do
product { |pd| Spree::Product.first || FactoryGirl.create(:product) }
distributor { |pd| Enterprise.is_distributor.first || FactoryGirl.create(:distributor_enterprise) }
shipping_method { |pd| Spree::ShippingMethod.where("name != 'Delivery'").first || FactoryGirl.create(:shipping_method) }
enterprise_fee { |pd| FactoryGirl.create(:enterprise_fee, enterprise: pd.distributor) }
end
@@ -97,6 +97,14 @@ FactoryGirl.define do
calculator { FactoryGirl.build(:itemwise_calculator) }
end
factory :adjustment_metadata, :class => AdjustmentMetadata do
adjustment { FactoryGirl.create(:adjustment) }
enterprise { FactoryGirl.create(:distributor_enterprise) }
fee_name 'fee'
fee_type 'packing'
enterprise_role 'distributor'
end
factory :itemwise_calculator, :class => OpenFoodWeb::Calculator::Itemwise do
end
@@ -126,19 +134,6 @@ FactoryGirl.modify do
supplier { Enterprise.is_primary_producer.first || FactoryGirl.create(:supplier_enterprise) }
on_hand 3
# before(:create) do |product, evaluator|
# product.product_distributions = [FactoryGirl.create(:product_distribution, :product => product)]
# end
# Do not create products distributed via the 'Delivery' shipping method
after(:create) do |product, evaluator|
pd = product.product_distributions.first
if pd.andand.shipping_method.andand.name == 'Delivery'
pd.shipping_method = Spree::ShippingMethod.where("name != 'Delivery'").first || FactoryGirl.create(:shipping_method)
pd.save!
end
end
end
factory :shipping_method do

View File

@@ -17,7 +17,7 @@ feature %q{
end
scenario "listing enterprise fees" do
fee = create(:enterprise_fee)
fee = create(:enterprise_fee, name: '$0.50 / kg')
login_to_admin_section
click_link 'Configuration'
@@ -99,4 +99,27 @@ feature %q{
page.should_not have_selector "input[value='#{fee.name}']"
end
scenario "deleting a shipping method referenced by a product distribution" do
# Given an enterprise fee referenced by a product distribution
fee = create(:enterprise_fee)
p = create(:product)
d = create(:distributor_enterprise)
create(:product_distribution, product: p, distributor: d, enterprise_fee: fee)
# When I go to the enterprise fees page
login_to_admin_section
click_link 'Configuration'
click_link 'Enterprise Fees'
# And I click delete
find("a.delete-resource").click
# Then I should see an error
page.should have_content "That enterprise fee cannot be deleted as it is referenced by a product distribution: #{p.id} - #{p.name}."
# And my enterprise fee should not have been deleted
visit admin_enterprise_fees_path
page.should have_selector "input[value='#{fee.name}']"
EnterpriseFee.find(fee.id).should_not be_nil
end
end

View File

@@ -10,7 +10,7 @@ feature %q{
background do
@supplier = create(:supplier_enterprise, :name => 'New supplier')
@distributors = (1..3).map { create(:distributor_enterprise) }
@shipping_method = create(:shipping_method, :name => 'My shipping method')
@enterprise_fees = (0..2).map { |i| create(:enterprise_fee, enterprise: @distributors[i]) }
end
context "creating a product" do
@@ -25,9 +25,9 @@ feature %q{
select 'New supplier', :from => 'product_supplier_id'
check @distributors[0].name
select 'My shipping method', :from => 'product_product_distributions_attributes_0_shipping_method_id'
select @enterprise_fees[0].name, :from => 'product_product_distributions_attributes_0_enterprise_fee_id'
check @distributors[2].name
select 'My shipping method', :from => 'product_product_distributions_attributes_2_shipping_method_id'
select @enterprise_fees[2].name, :from => 'product_product_distributions_attributes_2_enterprise_fee_id'
click_button 'Create'
@@ -35,7 +35,7 @@ feature %q{
product = Spree::Product.find_by_name('A new product !!!')
product.supplier.should == @supplier
product.distributors.should == [@distributors[0], @distributors[2]]
product.product_distributions.map { |pd| pd.shipping_method }.should == [@shipping_method, @shipping_method]
product.product_distributions.map { |pd| pd.enterprise_fee }.should == [@enterprise_fees[0], @enterprise_fees[2]]
product.group_buy.should be_false
end
@@ -60,7 +60,7 @@ feature %q{
end
describe 'As an enterprise user' do
context "as an enterprise user" do
before(:each) do
@new_user = create_enterprise_user
@@ -87,7 +87,7 @@ feature %q{
end
check @distributors[0].name
select 'My shipping method', :from => 'product_product_distributions_attributes_0_shipping_method_id'
select @enterprise_fees[0].name, :from => 'product_product_distributions_attributes_0_enterprise_fee_id'
# Should only have distributors listed which the user can manage
within "#product_product_distributions_field" do

View File

@@ -54,7 +54,7 @@ feature %q{
@distributor_address = create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234")
@distributor = create(:distributor_enterprise, :address => @distributor_address)
product = create(:product)
product_distribution = create(:product_distribution, :product => product, :distributor => @distributor, :shipping_method => create(:shipping_method))
product_distribution = create(:product_distribution, :product => product, :distributor => @distributor)
@shipping_instructions = "pick up on thursday please!"
@order1 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions)
@order2 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions)

View File

@@ -26,15 +26,4 @@ feature 'shipping methods' do
page.should have_content "That shipping method cannot be deleted as it is referenced by an order: #{o.number}."
Spree::ShippingMethod.find(@sm.id).should_not be_nil
end
scenario "deleting a shipping method referenced by a product distribution" do
p = create(:product)
d = create(:distributor_enterprise)
create(:product_distribution, product: p, distributor: d, shipping_method: @sm)
visit_delete spree.admin_shipping_method_path(@sm)
page.should have_content "That shipping method cannot be deleted as it is referenced by a product distribution: #{p.id} - #{p.name}."
Spree::ShippingMethod.find(@sm.id).should_not be_nil
end
end

View File

@@ -92,6 +92,26 @@ module Spree
it "should not be able to read/write other enterprises' orders" do
should_not have_ability([:admin, :index, :read, :edit], for: o2)
end
it "should be able to create a new order" do
should have_ability(:create, for: Spree::Order)
end
it "should be able to read/write Payments on a product" do
should have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Payment)
end
it "should be able to read/write Shipments on a product" do
should have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Shipment)
end
it "should be able to read/write Adjustments on a product" do
should have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Adjustment)
end
it "should be able to read/write ReturnAuthorizations on a product" do
should have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::ReturnAuthorization)
end
end
end

View File

@@ -0,0 +1,6 @@
describe AdjustmentMetadata do
it "is valid when build from factory" do
adjustment = create(:adjustment)
adjustment.should be_valid
end
end

View File

@@ -0,0 +1,8 @@
module Spree
describe Adjustment do
it "has metadata" do
adjustment = create(:adjustment, metadata: create(:adjustment_metadata))
adjustment.metadata.should be
end
end
end

View File

@@ -57,7 +57,11 @@ describe ProductDistribution do
adjustment.amount.should == 1.23
# And it should have some associated metadata
pending 'Needs metadata spec'
md = adjustment.metadata
md.enterprise.should == distributor
md.fee_name.should == enterprise_fee.name
md.fee_type.should == enterprise_fee.fee_type
md.enterprise_role.should == 'distributor'
end
end
@@ -152,6 +156,12 @@ describe ProductDistribution do
adjustment.source.should == line_item
adjustment.originator.should == pd.enterprise_fee
adjustment.should be_mandatory
md = adjustment.metadata
md.enterprise.should == pd.distributor
md.fee_name.should == pd.enterprise_fee.name
md.fee_type.should == pd.enterprise_fee.fee_type
md.enterprise_role.should == 'distributor'
end
end

View File

@@ -1,11 +1,11 @@
# Initialise shipping method when created without one, like this:
# Initialise enterprise fee when created without one, like this:
# create(:product, :distributors => [...])
# In this case, we don't care what the shipping method is, but we need one for validations to pass.
# In this case, we don't care what the fee is, but we need one for validations to pass.
ProductDistribution.class_eval do
before_validation :init_shipping_method
before_validation :init_enterprise_fee
def init_shipping_method
self.shipping_method ||= Spree::ShippingMethod.first || FactoryGirl.create(:shipping_method)
def init_enterprise_fee
self.enterprise_fee ||= EnterpriseFee.where(enterprise_id: distributor).first || FactoryGirl.create(:enterprise_fee, enterprise_id: distributor)
end
end