diff --git a/app/assets/stylesheets/store/openfoodweb.css.scss b/app/assets/stylesheets/store/openfoodweb.css.scss
index 24c0b1fd5a..3e91985fe9 100644
--- a/app/assets/stylesheets/store/openfoodweb.css.scss
+++ b/app/assets/stylesheets/store/openfoodweb.css.scss
@@ -225,3 +225,13 @@ fieldset#product-distributor-details {
}
}
}
+
+/* Alert for EFT Payment during checkout process */
+div#eft-payment-alert {
+ border: 2px solid red;
+}
+
+/* Cleared div for clearing previous floating elements */
+div.cleared {
+ clear: both;
+}
diff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb
index 1b05eaf1c3..1290530ddd 100644
--- a/app/controllers/enterprises_controller.rb
+++ b/app/controllers/enterprises_controller.rb
@@ -26,28 +26,4 @@ class EnterprisesController < BaseController
@searcher = Spree::Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
-
- def select_distributor
- distributor = Enterprise.is_distributor.find params[:id]
-
- order = current_order(true)
-
- if order.can_change_distributor?
- order.distributor = distributor
- order.save!
- end
-
- redirect_to distributor
- end
-
- def deselect_distributor
- order = current_order(true)
-
- if order.can_change_distributor?
- order.distributor = nil
- order.save!
- end
-
- redirect_to root_path
- end
end
diff --git a/app/controllers/spree/orders_controller_decorator.rb b/app/controllers/spree/orders_controller_decorator.rb
index 5d6fb8fb18..ca7978e64a 100644
--- a/app/controllers/spree/orders_controller_decorator.rb
+++ b/app/controllers/spree/orders_controller_decorator.rb
@@ -49,6 +49,24 @@ Spree::OrdersController.class_eval do
end
end
+ def select_distributor
+ distributor = Enterprise.is_distributor.find params[:id]
+
+ order = current_order(true)
+ order.distributor = distributor
+ order.save!
+
+ redirect_to main_app.enterprise_path(distributor)
+ end
+
+ def deselect_distributor
+ order = current_order(true)
+
+ order.distributor = nil
+ order.save!
+
+ redirect_to root_path
+ end
private
@@ -69,7 +87,7 @@ Spree::OrdersController.class_eval do
# -- If products in cart, distributor can't be changed
order = current_order(false)
- if !order.nil? && !order.can_change_distributor? && order.distributor != distributor
+ if !order.nil? && !DistributorChangeValidator.new(order).can_change_to_distributor?(distributor)
return false
end
diff --git a/app/helpers/enterprises_helper.rb b/app/helpers/enterprises_helper.rb
index fb8a9a13bc..a1012dbe1c 100644
--- a/app/helpers/enterprises_helper.rb
+++ b/app/helpers/enterprises_helper.rb
@@ -2,4 +2,8 @@ module EnterprisesHelper
def current_distributor
@current_distributor ||= current_order(false).andand.distributor
end
+
+ def enterprises_options enterprises
+ enterprises.map { |enterprise| [enterprise.name + ": " + enterprise.address.address1 + ", " + enterprise.address.city, enterprise.id.to_i] }
+ end
end
diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb
index 7c89d20bf8..08d5e5492f 100644
--- a/app/helpers/spree/orders_helper.rb
+++ b/app/helpers/spree/orders_helper.rb
@@ -5,5 +5,9 @@ module Spree
amount = order.line_items.map { |li| li.itemwise_shipping_cost }.sum
options.delete(:format_as_currency) ? number_to_currency(amount) : amount
end
+
+ def alternative_available_distributors(order)
+ DistributorChangeValidator.new(order).available_distributors(Enterprise.all) - [order.distributor]
+ end
end
end
diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb
index d4679f6424..17c9380097 100644
--- a/app/models/enterprise.rb
+++ b/app/models/enterprise.rb
@@ -27,6 +27,10 @@ class Enterprise < ActiveRecord::Base
def to_param
"#{id}-#{name.parameterize}"
end
+
+ def available_variants
+ ProductDistribution.find_all_by_distributor_id( self.id ).map{ |pd| pd.product.variants + [pd.product.master] }.flatten
+ end
private
diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb
index 449640a4b6..17dbe09405 100644
--- a/app/models/spree/order_decorator.rb
+++ b/app/models/spree/order_decorator.rb
@@ -1,17 +1,18 @@
+require 'open_food_web/distributor_change_validator'
+
Spree::Order.class_eval do
belongs_to :distributor, :class_name => 'Enterprise'
before_validation :shipping_address_from_distributor
+ validate :products_available_from_new_distributor, :if => :distributor_id_changed?
+ attr_accessible :distributor_id
+
after_create :set_default_shipping_method
- def can_change_distributor?
- # Distributor may not be changed once an item has been added to the cart/order
- line_items.empty?
- end
-
- def distributor=(distributor)
- raise "You cannot change the distributor of an order with products" unless distributor == self.distributor || can_change_distributor?
- super(distributor)
+
+ def products_available_from_new_distributor
+ # Check that the line_items in the current order are available from a newly selected distributor
+ errors.add(:distributor_id, "cannot supply the products in your cart") unless DistributorChangeValidator.new(self).can_change_to_distributor?(distributor)
end
def set_distributor!(distributor)
@@ -19,11 +20,6 @@ Spree::Order.class_eval do
save!
end
-
- def can_add_product_to_cart?(product)
- can_change_distributor? || product.distributors.include?(distributor)
- end
-
def set_variant_attributes(variant, attributes)
line_item = contains?(variant)
@@ -34,6 +30,10 @@ Spree::Order.class_eval do
line_item.assign_attributes(attributes)
line_item.save!
end
+
+ def line_item_variants
+ line_items.map{ |li| li.variant }
+ end
private
diff --git a/app/overrides/add_cms_checkout_distribution.rb b/app/overrides/add_cms_checkout_distribution.rb
index 28e45b6290..e1c1d5b7b5 100644
--- a/app/overrides/add_cms_checkout_distribution.rb
+++ b/app/overrides/add_cms_checkout_distribution.rb
@@ -1,4 +1,4 @@
Deface::Override.new(:virtual_path => "spree/checkout/_delivery",
:insert_before => "fieldset#shipping_method",
- :text => "<%= cms_page_content(:content, Cms::Page.find_by_full_path('/delivery')) %>",
- :name => "process_my_order_button")
\ No newline at end of file
+ :text => "<%= cms_snippet_content(Cms::Snippet.find_by_identifier('distribution')) %>",
+ :name => "cms_checkout_distribution")
\ No newline at end of file
diff --git a/app/overrides/add_cms_to_cart.rb b/app/overrides/add_cms_to_cart.rb
new file mode 100644
index 0000000000..9be4e4a65d
--- /dev/null
+++ b/app/overrides/add_cms_to_cart.rb
@@ -0,0 +1,4 @@
+Deface::Override.new(:virtual_path => "spree/orders/edit",
+ :insert_after => "h1",
+ :text => "<%= cms_snippet_content(Cms::Snippet.find_by_identifier('cart')) %>",
+ :name => "cms_to_cart")
\ No newline at end of file
diff --git a/app/overrides/order_item_description.rb b/app/overrides/order_item_description.rb
new file mode 100644
index 0000000000..ae1a28ecd2
--- /dev/null
+++ b/app/overrides/order_item_description.rb
@@ -0,0 +1,4 @@
+Deface::Override.new(:virtual_path => "spree/shared/_order_details",
+ :replace => "[data-hook='order_item_description']",
+ :partial => "spree/orders/order_item_description",
+ :name => "order_item_description")
\ No newline at end of file
diff --git a/app/overrides/replace_delivery_address.rb b/app/overrides/replace_delivery_address.rb
index 2b13785b1c..60b9883d5f 100644
--- a/app/overrides/replace_delivery_address.rb
+++ b/app/overrides/replace_delivery_address.rb
@@ -1,4 +1,9 @@
Deface::Override.new(:virtual_path => "spree/checkout/_address",
- :replace => "[data-hook='shipping_fieldset_wrapper']",
- :partial => "spree/checkout/distributor",
- :name => "delivery_address")
+ :replace => "[data-hook='shipping_fieldset_wrapper']",
+ :partial => "spree/checkout/distributor",
+ :name => "replace_shipping_form")
+
+Deface::Override.new(:virtual_path => "spree/checkout/edit",
+ :insert_after => "[data-hook='checkout_summary_box']",
+ :partial => "spree/checkout/other_available_distributors",
+ :name => "other_available_distributors")
diff --git a/app/overrides/replace_order_details_steps_data.rb b/app/overrides/replace_order_details_steps_data.rb
new file mode 100644
index 0000000000..10b307cd1c
--- /dev/null
+++ b/app/overrides/replace_order_details_steps_data.rb
@@ -0,0 +1,4 @@
+Deface::Override.new(:virtual_path => "spree/shared/_order_details",
+ :replace => "div.row.steps-data",
+ :partial => "spree/shared/order_details_steps_data",
+ :name => "order_details_steps_data")
\ No newline at end of file
diff --git a/app/views/spree/checkout/_other_available_distributors.html.erb b/app/views/spree/checkout/_other_available_distributors.html.erb
new file mode 100644
index 0000000000..d9f4560cb7
--- /dev/null
+++ b/app/views/spree/checkout/_other_available_distributors.html.erb
@@ -0,0 +1,13 @@
+<% unless @order.state != 'address' %>
+
+ <% unless alternative_available_distributors(@order).empty? %>
+ <%= form_for(@order) do |f| %>
+ <%= f.label :distributor_label, "Alternative distributors for this order:" %>
+ <%= f.select :distributor_id, options_for_select( enterprises_options(alternative_available_distributors(@order)) ) %>
+ <%= f.submit "Change Distributor" %>
+ <% end %>
+ <% else %>
+ No alternative distributors available.
+ <% end %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/spree/orders/_cart_item_description.html.haml b/app/views/spree/orders/_cart_item_description.html.haml
index ff04782b44..9a516168bc 100644
--- a/app/views/spree/orders/_cart_item_description.html.haml
+++ b/app/views/spree/orders/_cart_item_description.html.haml
@@ -4,5 +4,4 @@
- if @order.insufficient_stock_lines.include? line_item
%span.out-of-stock
= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock)
- %br/
- = truncate_html(variant.product.description, :length => 100, :omission => "...")
+ %br/
\ No newline at end of file
diff --git a/app/views/spree/orders/_distributor_fees.html.haml b/app/views/spree/orders/_distributor_fees.html.haml
index 1b3633eb6a..ff3e640c2d 100644
--- a/app/views/spree/orders/_distributor_fees.html.haml
+++ b/app/views/spree/orders/_distributor_fees.html.haml
@@ -1,6 +1,6 @@
#delivery-fees
- = cms_page_content(:content, Cms::Page.find_by_full_path('/cart-delivery-fees'))
- %h2 Delivery Fees
+ %h2 Distribution Costs
+ = cms_snippet_content(Cms::Snippet.find_by_identifier('cart_distribution_costs'))
%table#delivery
%thead
diff --git a/app/views/spree/orders/_order_item_description.html.haml b/app/views/spree/orders/_order_item_description.html.haml
new file mode 100644
index 0000000000..d4531e8976
--- /dev/null
+++ b/app/views/spree/orders/_order_item_description.html.haml
@@ -0,0 +1,3 @@
+%td(data-hook = "order_item_description")
+ %h4= item.variant.product.name
+ = "(" + variant_options(item.variant) + ")" unless item.variant.option_values.empty?
\ No newline at end of file
diff --git a/app/views/spree/products/_add_to_cart.html.haml b/app/views/spree/products/_add_to_cart.html.haml
index e934cebe21..0b0e118e54 100644
--- a/app/views/spree/products/_add_to_cart.html.haml
+++ b/app/views/spree/products/_add_to_cart.html.haml
@@ -1,26 +1,34 @@
.add-to-cart
+ - order = current_order(false)
- if !@product.has_stock? && !Spree::Config[:allow_backorders]
= content_tag('strong', t(:out_of_stock))
- - elsif current_order(false) && !current_order(false).can_add_product_to_cart?(@product)
+ - elsif !order.nil? && !DistributorChangeValidator.new(order).can_change_distributor? && !@product.distributors.include?(order.distributor)
.error-distributor
Please complete your order at
= link_to current_distributor.name, root_path
before shopping with another distributor.
-
- else
- %p Quantity
- = number_field_tag (@product.has_variants? ? :quantity : "variants[#{@product.master.id}]"), 1, :class => 'title', :in => 1..@product.on_hand
+ %div(class = "columns alpha two")
+ %div Quantity
+ = number_field_tag (@product.has_variants? ? :quantity : "variants[#{@product.master.id}]"), 1, :class => 'title', :in => 1..@product.on_hand
- if @product.group_buy
- %p Max quantity
- = number_field_tag (@product.has_variants? ? :max_quantity : "variant_attributes[#{@product.master.id}][max_quantity]"), 1, :class => 'title max_quantity', :in => 1..@product.on_hand
- - order = current_order(false)
- - if order.nil? || order.can_change_distributor?
- %p Distributor
- = select_tag "distributor_id", options_from_collection_for_select([Enterprise.new]+@product.distributors, "id", "name", current_distributor.andand.id)
- - else
- = hidden_field_tag "distributor_id", order.distributor.id
- .distributor-fixed= "Your distributor for this order is #{order.distributor.name}"
- %br/
+ %div(class = "columns alpha three")
+ %div Max quantity
+ = number_field_tag (@product.has_variants? ? :max_quantity : "variant_attributes[#{@product.master.id}][max_quantity]"), 1, :class => 'title max_quantity', :in => 1..@product.on_hand
+ %div.cleared
+ %br
+ - if order.nil? || order.distributor.nil?
+ %div Distributor for your order:
+ = select_tag "distributor_id", options_from_collection_for_select([Enterprise.new]+@product.distributors, "id", "name", :include_blank => '')
+ - else
+ - available_distributors = DistributorChangeValidator.new(order).available_distributors(@product.distributors)
+ - if available_distributors.length > 1
+ %div Distributor for your order:
+ = select_tag "distributor_id", options_from_collection_for_select(available_distributors, "id", "name", current_distributor.andand.id)
+ - else
+ = hidden_field_tag "distributor_id", order.distributor.id
+ .distributor-fixed= "Your distributor for this order is #{order.distributor.name}"
+ %br
= button_tag :class => 'large primary', :id => 'add-to-cart-button', :type => :submit do
- = t(:add_to_cart)
+ = t(:add_to_cart)
\ No newline at end of file
diff --git a/app/views/spree/products/_source.html.haml b/app/views/spree/products/_source.html.haml
index dc7f033b91..0757658c0e 100644
--- a/app/views/spree/products/_source.html.haml
+++ b/app/views/spree/products/_source.html.haml
@@ -1,17 +1,30 @@
%div{:data-hook => "product_source"}
- %h6.product-section-title Source
+ %h6.product-section-title SUPPLIER
%table#product-source.table-display{:width => "100%"}
%tbody
- if @product.supplier
%tr.odd
- %td
- %strong Supplier
- %td= @product.supplier.name
+ %td= link_to @product.supplier.name, [main_app, @product.supplier]
%br/
+ %h6.product-section-title DISTRIBUTORS
%table#product-source.table-display{:width => "100%"}
%tbody
+ - order = current_order(false)
+ - validator = DistributorChangeValidator.new(order)
- @product.distributors.each do |distributor|
- %tr.even
- %td
- %strong Distributor
- %td= distributor.name
+ - if !order.nil? && distributor == order.distributor
+ %tr.odd
+ %td
+ %b= link_to(distributor.name, [main_app, distributor])
+ %td
+ %b Current
+ - elsif order.nil? || validator.can_change_to_distributor?(distributor)
+ %tr.even
+ %td= link_to distributor.name, [main_app, distributor]
+ %td Available
+ -#%td= link_to "Change to distributor", select_distributor_order_path(distributor)
+ - else
+ %tr.even
+ %td= link_to distributor.name, [main_app, distributor]
+ %td
+
\ No newline at end of file
diff --git a/app/views/spree/products/_source_sidebar.html.haml b/app/views/spree/products/_source_sidebar.html.haml
index bd25db53a0..03fc78ac84 100644
--- a/app/views/spree/products/_source_sidebar.html.haml
+++ b/app/views/spree/products/_source_sidebar.html.haml
@@ -9,13 +9,14 @@
%h6.filter_name Shop by Distributor
%ul.filter_choices
- order = current_order(false)
+ - validator = DistributorChangeValidator.new(order)
- @distributors.each do |distributor|
%li.nowrap
- - if order.nil? || order.can_change_distributor?
- = link_to distributor.name, main_app.select_distributor_enterprise_path(distributor)
+ - if order.nil? || validator.can_change_to_distributor?(distributor)
+ = link_to distributor.name, [main_app, distributor]
- elsif order.distributor == distributor
= link_to distributor.name, [main_app, distributor]
- else
- %span.inactive= distributor.name
- - if current_distributor && order.can_change_distributor?
- = button_to 'Browse All Distributors', main_app.deselect_distributor_enterprises_path, :method => :get
+ %abbr(title="One or more of the products in your cart is not available from this distributor")= distributor.name
+ - if current_distributor && validator.can_change_distributor?
+ = button_to 'Browse All Distributors', deselect_distributor_orders_path, :method => :get
diff --git a/app/views/spree/shared/_order_details_steps_data.html.erb b/app/views/spree/shared/_order_details_steps_data.html.erb
new file mode 100644
index 0000000000..96214287f8
--- /dev/null
+++ b/app/views/spree/shared/_order_details_steps_data.html.erb
@@ -0,0 +1,49 @@
+
+
+
+
<%= "Customer Details" %> <%= link_to "(#{t(:edit)})", checkout_state_path(:address) unless @order.completed? %>
+
+ Name: <%= order.bill_address.full_name %>
+ Address: <%= order.bill_address.address1 + ", " + order.bill_address.city %>
+
+
+
+
+
<%= "Distributor Details" %> <%# link_to "(#{t(:edit)})", checkout_state_path(:address) unless @order.completed? %>
+
+ Distributor: <%= order.distributor.name %>
+ Address: <%= order.distributor.address.address1 + ", " + order.distributor.address.city %>
+
+
+
+
+
+
+
id="eft-payment-alert"<% end %>>
+
<%= t(:payment_information) %> <%= link_to "(#{t(:edit)})", checkout_state_path(:payment) unless @order.completed? %>
+
+ <% if order.payment_method.name.include? "PayPal" %>
+
Your payment via PayPal has been processed successfully.
+ <% elsif order.payment_method.name.include? "EFT" %>
+
<%= order.payment_method.description.html_safe %>
+ <% elsif order.creditcards.empty? == false %>
+
+ <%= image_tag "creditcards/icons/#{order.creditcards.first.cc_type}.png" %>
+ <%= t(:ending_in)%> <%= order.creditcards.first.last_digits %>
+
+
+
+ <%= order.creditcards.first.first_name %>
+ <%= order.creditcards.first.last_name %>
+
+ <% elsif order.payment_method.type == "Spree::PaymentMethod::Check" %>
+
<%= order.payment_method.description %>
+ <% end %>
+
+
+
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 7bbbf022f3..11ab6cb5a3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,8 +4,6 @@ Openfoodweb::Application.routes.draw do
resources :enterprises do
get :suppliers, :on => :collection
get :distributors, :on => :collection
- get :select_distributor, :on => :member
- get :deselect_distributor, :on => :collection
end
namespace :admin do
@@ -33,4 +31,9 @@ Spree::Core::Engine.routes.prepend do
match '/admin/reports/bulk_coop' => 'admin/reports#bulk_coop', :as => "bulk_coop_admin_reports", :via => [:get, :post]
match '/admin/reports/payments' => 'admin/reports#payments', :as => "payments_admin_reports", :via => [:get, :post]
match '/admin/reports/order_cycles' => 'admin/reports#order_cycles', :as => "order_cycles_admin_reports", :via => [:get, :post]
+
+ resources :orders do
+ get :select_distributor, :on => :member
+ get :deselect_distributor, :on => :collection
+ end
end
diff --git a/lib/open_food_web/distributor_change_validator.rb b/lib/open_food_web/distributor_change_validator.rb
new file mode 100644
index 0000000000..ca7545eefc
--- /dev/null
+++ b/lib/open_food_web/distributor_change_validator.rb
@@ -0,0 +1,22 @@
+class DistributorChangeValidator
+
+ def initialize order
+ @order = order
+ end
+
+ def can_change_distributor?
+ # Distributor may not be changed once an item has been added to the cart/order
+ @order.line_items.empty?
+ end
+
+ def can_change_to_distributor? distributor
+ # Distributor may not be changed once an item has been added to the cart/order, unless all items are available from the specified distributor
+ @order.line_items.empty? || (available_distributors(Enterprise.all) || []).include?(distributor)
+ end
+
+ def available_distributors enterprises
+ enterprises.select do |e|
+ (@order.line_item_variants - e.available_variants).empty?
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/controllers/enterprises_controller_spec.rb b/spec/controllers/enterprises_controller_spec.rb
index 1554984dfb..a5709d3a74 100644
--- a/spec/controllers/enterprises_controller_spec.rb
+++ b/spec/controllers/enterprises_controller_spec.rb
@@ -19,65 +19,4 @@ describe EnterprisesController do
assigns(:suppliers).should == [s]
end
-
- it "selects distributors" do
- d = create(:distributor_enterprise)
-
- spree_get :select_distributor, :id => d.id
- response.should be_redirect
-
- order = current_order(false)
- order.distributor.should == d
- end
-
- it "deselects distributors" do
- d = create(:distributor_enterprise)
- order = current_order(true)
- order.distributor = d
- order.save!
-
- spree_get :deselect_distributor
- response.should be_redirect
-
- order.reload
- order.distributor.should be_nil
- end
-
- context "when a product has been added to the cart" do
- it "does not allow selecting another distributor" do
- # Given some distributors and an order with a product
- d1 = create(:distributor_enterprise)
- d2 = create(:distributor_enterprise)
- p = create(:product, :distributors => [d1])
- o = current_order(true)
-
- o.distributor = d1
- o.save!
- o.add_variant(p.master, 1)
-
- # When I attempt to select a distributor
- spree_get :select_distributor, :id => d2.id
-
- # Then my distributor should remain unchanged
- o.reload
- o.distributor.should == d1
- end
-
- it "does not allow deselecting distributors" do
- # Given a distributor and an order with a product
- d = create(:distributor_enterprise)
- p = create(:product, :distributors => [d])
- o = current_order(true)
- o.distributor = d
- o.save!
- o.add_variant(p.master, 1)
-
- # When I attempt to deselect the distributor
- spree_get :deselect_distributor
-
- # Then my distributor should remain unchanged
- o.reload
- o.distributor.should == d
- end
- end
end
diff --git a/spec/controllers/orders_controller_spec.rb b/spec/controllers/orders_controller_spec.rb
index ded96678dd..440bf8fcbf 100644
--- a/spec/controllers/orders_controller_spec.rb
+++ b/spec/controllers/orders_controller_spec.rb
@@ -7,7 +7,32 @@ describe Spree::OrdersController do
def current_user
controller.current_user
end
+
+ it "selects distributors" do
+ d = create(:distributor_enterprise)
+ p = create(:product, :distributors => [d])
+ spree_get :select_distributor, :id => d.id
+ response.should be_redirect
+
+ order = current_order(false)
+ order.distributor.should == d
+ end
+
+ it "deselects distributors" do
+ d = create(:distributor_enterprise)
+ p = create(:product, :distributors => [d])
+
+ order = current_order(true)
+ order.distributor = d
+ order.save!
+
+ spree_get :deselect_distributor
+ response.should be_redirect
+
+ order.reload
+ order.distributor.should be_nil
+ end
context "adding the first product to the cart" do
it "does not add the product if the user does not specify a distributor" do
diff --git a/spec/lib/open_food_web/distributor_change_validator_spec.rb b/spec/lib/open_food_web/distributor_change_validator_spec.rb
new file mode 100644
index 0000000000..d8f8967000
--- /dev/null
+++ b/spec/lib/open_food_web/distributor_change_validator_spec.rb
@@ -0,0 +1,80 @@
+require 'open_food_web/distributor_change_validator'
+
+describe DistributorChangeValidator do
+ let(:order) { double(:order) }
+ let(:subject) { DistributorChangeValidator.new(order) }
+
+ context "permissions for changing distributor" do
+ it "allows distributor to be changed if line_items is empty" do
+ order.stub(:line_items) { [] }
+ subject.can_change_distributor?.should be_true
+ end
+
+ it "does not allow distributor to be changed if line_items is not empty" do
+ order.stub(:line_items) { [1, 2, 3] }
+ subject.can_change_distributor?.should be_false
+ end
+ end
+
+ context "finding distributors which have the same variants" do
+ it "matches enterprises which offer all products within the order" do
+ variant1 = double(:variant)
+ variant2 = double(:variant)
+ variant3 = double(:variant)
+ variant5 = double(:variant)
+ line_item_variants = [variant1, variant3, variant5]
+ order.stub(:line_item_variants){ line_item_variants }
+ enterprise = double(:enterprise)
+ enterprise.stub(:available_variants){ line_item_variants } # Exactly the same variants as the order
+
+ subject.available_distributors([enterprise]).should == [enterprise]
+ end
+
+ it "does not match enterprises with no products available" do
+ variant1 = double(:variant)
+ variant3 = double(:variant)
+ variant5 = double(:variant)
+ line_item_variants = [variant1, variant3, variant5]
+ order.stub(:line_item_variants){ line_item_variants }
+ enterprise = double(:enterprise)
+ enterprise.stub(:available_variants){ [] } # No variants
+
+ subject.available_distributors([enterprise]).should_not include enterprise
+ end
+
+ it "does not match enterprises with only some of the same variants in the order available" do
+ variant1 = double(:variant)
+ variant2 = double(:variant)
+ variant3 = double(:variant)
+ variant4 = double(:variant)
+ variant5 = double(:variant)
+ line_item_variants = [variant1, variant3, variant5]
+ order.stub(:line_item_variants){ line_item_variants }
+ enterprise_with_some_variants = double(:enterprise)
+ enterprise_with_some_variants.stub(:available_variants){ [variant1, variant3] } # Only some variants
+ enterprise_with_some_plus_extras = double(:enterprise)
+ enterprise_with_some_plus_extras.stub(:available_variants){ [variant1, variant2, variant3, variant4] } # Only some variants, plus extras
+
+ subject.available_distributors([enterprise_with_some_variants]).should_not include enterprise_with_some_variants
+ subject.available_distributors([enterprise_with_some_plus_extras]).should_not include enterprise_with_some_plus_extras
+ end
+
+ it "matches enteprises which offer all products in the order, plus additional products" do
+ variant1 = double(:variant)
+ variant2 = double(:variant)
+ variant3 = double(:variant)
+ variant4 = double(:variant)
+ variant5 = double(:variant)
+ line_item_variants = [variant1, variant3, variant5]
+ order.stub(:line_item_variants){ line_item_variants }
+ enterprise = double(:enterprise)
+ enterprise.stub(:available_variants){ [variant1, variant2, variant3, variant4, variant5] } # Excess variants
+
+ subject.available_distributors([enterprise]).should == [enterprise]
+ end
+
+ it "matches no enterprises when none are provided" do
+ subject.available_distributors([]).should == []
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/models/order_spec.rb b/spec/models/order_spec.rb
index 335c67a574..e3d52db8bb 100644
--- a/spec/models/order_spec.rb
+++ b/spec/models/order_spec.rb
@@ -14,58 +14,6 @@ describe Spree::Order do
subject.adjustments.where(:label => "Shipping").should be_present
end
- it "reveals permission for changing distributor" do
- d = create(:distributor_enterprise)
- p = create(:product, :distributors => [d])
-
- subject.distributor = d
- subject.save!
-
- subject.can_change_distributor?.should be_true
- subject.add_variant(p.master, 1)
- subject.can_change_distributor?.should be_false
- end
-
- it "raises an exception if distributor is changed without permission" do
- d = create(:distributor_enterprise)
- p = create(:product, :distributors => [d])
- subject.distributor = d
- subject.save!
-
- subject.add_variant(p.master, 1)
- subject.can_change_distributor?.should be_false
-
- expect do
- subject.distributor = nil
- end.to raise_error "You cannot change the distributor of an order with products"
- end
-
- it "reveals permission for adding products to the cart" do
- d1 = create(:distributor_enterprise)
- d2 = create(:distributor_enterprise)
-
- p_first = create(:product, :distributors => [d1])
- p_subsequent_same_dist = create(:product, :distributors => [d1])
- p_subsequent_other_dist = create(:product, :distributors => [d2])
-
- # We need to set distributor, since order.add_variant does not, and
- # we also need to save the order so that line items can be added to
- # the association.
- subject.distributor = d1
- subject.save!
-
- # The first product in the cart can be added
- subject.can_add_product_to_cart?(p_first).should be_true
- subject.add_variant(p_first.master, 1)
-
- # A subsequent product can be added if the distributor matches
- subject.can_add_product_to_cart?(p_subsequent_same_dist).should be_true
- subject.add_variant(p_subsequent_same_dist.master, 1)
-
- # And cannot be added if it does not match
- subject.can_add_product_to_cart?(p_subsequent_other_dist).should be_false
- end
-
it "sets attributes on line items for variants" do
d = create(:distributor_enterprise)
p = create(:product, :distributors => [d])
@@ -79,4 +27,38 @@ describe Spree::Order do
li = Spree::LineItem.last
li.max_quantity.should == 3
end
+
+ context "validating distributor changes" do
+ it "checks that a distributor is available when changing" do
+ order_enterprise = FactoryGirl.create(:enterprise, id: 1, :name => "Order Enterprise")
+ subject.distributor = order_enterprise
+ product1 = FactoryGirl.create(:product)
+ product2 = FactoryGirl.create(:product)
+ product3 = FactoryGirl.create(:product)
+ variant11 = FactoryGirl.create(:variant, product: product1)
+ variant12 = FactoryGirl.create(:variant, product: product1)
+ variant21 = FactoryGirl.create(:variant, product: product2)
+ variant31 = FactoryGirl.create(:variant, product: product3)
+ variant32 = FactoryGirl.create(:variant, product: product3)
+
+ # Product Distributions
+ # Order Enterprise sells product 1 and product 3
+ FactoryGirl.create(:product_distribution, product: product1, distributor: order_enterprise)
+ FactoryGirl.create(:product_distribution, product: product3, distributor: order_enterprise)
+
+ # Build the current order
+ line_item1 = FactoryGirl.create(:line_item, order: subject, variant: variant11)
+ line_item2 = FactoryGirl.create(:line_item, order: subject, variant: variant12)
+ line_item3 = FactoryGirl.create(:line_item, order: subject, variant: variant31)
+ subject.line_items = [line_item1,line_item2,line_item3]
+
+ test_enterprise = FactoryGirl.create(:enterprise, id: 2, :name => "Test Enterprise")
+ # Test Enterprise sells only product 1
+ FactoryGirl.create(:product_distribution, product: product1, distributor: test_enterprise)
+
+ subject.distributor = test_enterprise
+ subject.should_not be_valid
+ subject.errors.should include :distributor_id
+ end
+ end
end
diff --git a/spec/requests/consumer/checkout_spec.rb b/spec/requests/consumer/checkout_spec.rb
index 320dfcf281..c88f0da8ca 100644
--- a/spec/requests/consumer/checkout_spec.rb
+++ b/spec/requests/consumer/checkout_spec.rb
@@ -17,6 +17,16 @@ feature %q{
:state => Spree::State.find_by_name('Victoria'),
:country => Spree::Country.find_by_name('Australia')),
:pickup_times => 'Tuesday, 4 PM')
+
+
+ @distributor_alternative = create(:distributor_enterprise, :name => 'Alternative Distributor',
+ :address => create(:address,
+ :address1 => '1600 Rathdowne St',
+ :city => 'Carlton North',
+ :zipcode => 3054,
+ :state => Spree::State.find_by_name('Victoria'),
+ :country => Spree::Country.find_by_name('Australia')),
+ :pickup_times => 'Tuesday, 4 PM')
@shipping_method_1 = create(:shipping_method, :name => 'Shipping Method One')
@shipping_method_1.calculator.set_preference :amount, 1
@@ -28,9 +38,11 @@ feature %q{
@product_1 = create(:product, :name => 'Fuji apples')
@product_1.product_distributions.create(:distributor => @distributor, :shipping_method => @shipping_method_1)
+ @product_1.product_distributions.create(:distributor => @distributor_alternative, :shipping_method => @shipping_method_1)
@product_2 = create(:product, :name => 'Garlic')
@product_2.product_distributions.create(:distributor => @distributor, :shipping_method => @shipping_method_2)
+ @product_2.product_distributions.create(:distributor => @distributor_alternative, :shipping_method => @shipping_method_2)
@zone = create(:zone)
c = Spree::Country.find_by_name('Australia')
@@ -110,7 +122,9 @@ feature %q{
page.should have_content value
end
end
-
+
+ page.should have_selector "select#order_distributor_id option[value='#{@distributor_alternative.id}']"
+
click_button 'Save and Continue'
# -- Checkout: Delivery
diff --git a/spec/requests/consumer/distributors_spec.rb b/spec/requests/consumer/distributors_spec.rb
index 32e642edf5..4a747e5c0f 100644
--- a/spec/requests/consumer/distributors_spec.rb
+++ b/spec/requests/consumer/distributors_spec.rb
@@ -67,11 +67,10 @@ feature %q{
it "displays the distributor's name on the home page" do
# Given a distributor with a product
d = create(:distributor_enterprise, :name => 'Melb Uni Co-op', :description => 'Hello, world!
')
- create(:product, :distributors => [d])
+ p1 = create(:product, :distributors => [d])
# When I select the distributor
- visit spree.root_path
- click_link d.name
+ visit spree.select_distributor_order_path(d)
visit spree.root_path
# Then I should see the name of the distributor that I've selected
@@ -90,8 +89,7 @@ feature %q{
p2 = create(:product, :distributors => [d2], :taxons => [taxon])
# When I select the first distributor
- visit spree.root_path
- click_link d1.name
+ visit spree.select_distributor_order_path(d1)
visit spree.root_path
# Then I should see products split by local/remote distributor
@@ -112,11 +110,11 @@ feature %q{
it "allows the user to leave the distributor" do
# Given a distributor with a product
d = create(:distributor_enterprise, :name => 'Melb Uni Co-op')
- create(:product, :distributors => [d])
+ p1 = create(:product, :distributors => [d])
# When I select the distributor and then leave it
+ visit spree.select_distributor_order_path(d)
visit spree.root_path
- click_link d.name
click_button 'Browse All Distributors'
# Then I should have left the distributor
@@ -139,16 +137,16 @@ feature %q{
it "displays the local distributor as the default choice when available for the current product" do
# Given a distributor and a product under it
- distributor = create(:distributor_enterprise)
- product = create(:product, :distributors => [distributor])
+ distributor1 = create(:distributor_enterprise)
+ distributor2 = create(:distributor_enterprise)
+ product = create(:product, :distributors => [distributor1,distributor2])
# When we select the distributor and view the product
- visit spree.root_path
- click_link distributor.name
+ visit spree.select_distributor_order_path(distributor1)
visit spree.product_path(product)
# Then we should see our distributor as the default option when adding the item to our cart
- page.should have_selector "select#distributor_id option[value='#{distributor.id}'][selected='selected']"
+ page.should have_selector "select#distributor_id option[value='#{distributor1.id}'][selected='selected']"
end
it "works when viewing a product from a remote distributor" do
diff --git a/spec/requests/consumer/product_spec.rb b/spec/requests/consumer/product_spec.rb
index e8741548e2..1cd5f81574 100644
--- a/spec/requests/consumer/product_spec.rb
+++ b/spec/requests/consumer/product_spec.rb
@@ -36,8 +36,7 @@ feature %q{
d = create(:distributor_enterprise)
p = create(:product, :distributors => [d])
- visit spree.root_path
- click_link d.name
+ visit spree.select_distributor_order_path(d)
visit spree.product_path p
within '#product-distributor-details' do
diff --git a/spec/requests/consumer/taxonomy_spec.rb b/spec/requests/consumer/taxonomy_spec.rb
index 9a2190c1a0..47021bb848 100644
--- a/spec/requests/consumer/taxonomy_spec.rb
+++ b/spec/requests/consumer/taxonomy_spec.rb
@@ -49,7 +49,7 @@ feature %q{
2.times { create(:product, :taxons => [taxon_three], :distributors => [my_distributor]) }
# When I visit the home page and select my distributor
- visit spree.root_path
+ visit spree.select_distributor_order_path(my_distributor)
click_link my_distributor.name
page.should have_content 'You are shopping at My Distributor'