mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge branch 'checkout-changes'
Conflicts: .rvmrc app/helpers/application_helper.rb
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
:text => "<%= cms_snippet_content(Cms::Snippet.find_by_identifier('distribution')) %>",
|
||||
:name => "cms_checkout_distribution")
|
||||
4
app/overrides/add_cms_to_cart.rb
Normal file
4
app/overrides/add_cms_to_cart.rb
Normal file
@@ -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")
|
||||
4
app/overrides/order_item_description.rb
Normal file
4
app/overrides/order_item_description.rb
Normal file
@@ -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")
|
||||
@@ -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")
|
||||
|
||||
4
app/overrides/replace_order_details_steps_data.rb
Normal file
4
app/overrides/replace_order_details_steps_data.rb
Normal file
@@ -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")
|
||||
@@ -0,0 +1,13 @@
|
||||
<% unless @order.state != 'address' %>
|
||||
<div class="columns omega four" style="padding-top: 30px">
|
||||
<% 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 %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -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/
|
||||
@@ -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
|
||||
|
||||
3
app/views/spree/orders/_order_item_description.html.haml
Normal file
3
app/views/spree/orders/_order_item_description.html.haml
Normal file
@@ -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?
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
49
app/views/spree/shared/_order_details_steps_data.html.erb
Normal file
49
app/views/spree/shared/_order_details_steps_data.html.erb
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class="row steps-data">
|
||||
|
||||
<div class="columns alpha six">
|
||||
<h6><%= "Customer Details" %> <%= link_to "(#{t(:edit)})", checkout_state_path(:address) unless @order.completed? %></h6>
|
||||
<div class="address">
|
||||
Name: <%= order.bill_address.full_name %><br />
|
||||
Address: <%= order.bill_address.address1 + ", " + order.bill_address.city %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns alpha six">
|
||||
<h6><%= "Distributor Details" %> <%# link_to "(#{t(:edit)})", checkout_state_path(:address) unless @order.completed? %></h6>
|
||||
<div class="address">
|
||||
Distributor: <%= order.distributor.name %><br />
|
||||
Address: <%= order.distributor.address.address1 + ", " + order.distributor.address.city %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="columns alpha four">
|
||||
<h6><%= t(:shipping_method) %> <%= link_to "(#{t(:edit)})", checkout_state_path(:delivery) unless @order.completed? %></h6>
|
||||
<div class="delivery">
|
||||
<%= order.shipping_method.name %>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="row steps-data">
|
||||
<div class="columns alpha six" <% if order.payment_method.name.include? "EFT" %>id="eft-payment-alert"<% end %>>
|
||||
<h6><%= t(:payment_information) %> <%= link_to "(#{t(:edit)})", checkout_state_path(:payment) unless @order.completed? %></h6>
|
||||
<div class="payment-info">
|
||||
<% if order.payment_method.name.include? "PayPal" %>
|
||||
<div class="flash notice">Your payment via PayPal has been processed successfully.</div>
|
||||
<% elsif order.payment_method.name.include? "EFT" %>
|
||||
<span><%= order.payment_method.description.html_safe %></span>
|
||||
<% elsif order.creditcards.empty? == false %>
|
||||
<span class="cc-type">
|
||||
<%= image_tag "creditcards/icons/#{order.creditcards.first.cc_type}.png" %>
|
||||
<%= t(:ending_in)%> <%= order.creditcards.first.last_digits %>
|
||||
</span>
|
||||
<br />
|
||||
<span class="full-name">
|
||||
<%= order.creditcards.first.first_name %>
|
||||
<%= order.creditcards.first.last_name %>
|
||||
</span>
|
||||
<% elsif order.payment_method.type == "Spree::PaymentMethod::Check" %>
|
||||
<span><%= order.payment_method.description %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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
|
||||
|
||||
22
lib/open_food_web/distributor_change_validator.rb
Normal file
22
lib/open_food_web/distributor_change_validator.rb
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
80
spec/lib/open_food_web/distributor_change_validator_spec.rb
Normal file
80
spec/lib/open_food_web/distributor_change_validator_spec.rb
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 => '<p>Hello, world!</p>')
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user