mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Let people choose which payment methods are available to customers on order cycles
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/available_payment_method_filter'
|
||||
|
||||
module EnterprisesHelper
|
||||
def current_distributor
|
||||
@current_distributor ||= current_order(false)&.distributor
|
||||
@@ -18,18 +16,7 @@ module EnterprisesHelper
|
||||
end
|
||||
|
||||
def available_payment_methods
|
||||
return [] if current_distributor.blank?
|
||||
|
||||
payment_methods = current_distributor.payment_methods.available(:both).to_a
|
||||
|
||||
filter = OpenFoodNetwork::AvailablePaymentMethodFilter.new
|
||||
filter.filter!(payment_methods)
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(current_distributor,
|
||||
"FilterPaymentMethods", current_customer&.tag_list)
|
||||
applicator.filter!(payment_methods)
|
||||
|
||||
payment_methods
|
||||
OrderAvailablePaymentMethods.new(current_order, current_customer).to_a
|
||||
end
|
||||
|
||||
def managed_enterprises
|
||||
|
||||
@@ -399,7 +399,7 @@ class Enterprise < ApplicationRecord
|
||||
end
|
||||
|
||||
def ready_for_checkout?
|
||||
shipping_methods.frontend.any? && payment_methods.available.any?
|
||||
shipping_methods.frontend.any? && payment_methods.available.any?(&:configured?)
|
||||
end
|
||||
|
||||
def self.find_available_permalink(test_permalink)
|
||||
|
||||
@@ -24,6 +24,9 @@ class OrderCycle < ApplicationRecord
|
||||
has_many :distributors, -> { distinct }, source: :receiver, through: :cached_outgoing_exchanges
|
||||
has_many :order_cycle_schedules
|
||||
has_many :schedules, through: :order_cycle_schedules
|
||||
has_and_belongs_to_many :selected_distributor_payment_methods,
|
||||
class_name: 'DistributorPaymentMethod',
|
||||
join_table: 'order_cycles_distributor_payment_methods'
|
||||
has_and_belongs_to_many :selected_distributor_shipping_methods,
|
||||
class_name: 'DistributorShippingMethod',
|
||||
join_table: 'order_cycles_distributor_shipping_methods'
|
||||
@@ -152,12 +155,10 @@ class OrderCycle < ApplicationRecord
|
||||
]
|
||||
end
|
||||
|
||||
def attachable_payment_methods
|
||||
Spree::PaymentMethod.available(:both).
|
||||
joins("INNER JOIN distributors_payment_methods
|
||||
ON payment_method_id = spree_payment_methods.id").
|
||||
where("distributor_id IN (?)", distributor_ids).
|
||||
distinct
|
||||
def attachable_distributor_payment_methods
|
||||
DistributorPaymentMethod.joins(:payment_method).
|
||||
merge(Spree::PaymentMethod.available).
|
||||
where("distributor_id IN (?)", distributor_ids)
|
||||
end
|
||||
|
||||
def attachable_distributor_shipping_methods
|
||||
@@ -177,6 +178,9 @@ class OrderCycle < ApplicationRecord
|
||||
oc.schedule_ids = schedule_ids
|
||||
oc.save!
|
||||
exchanges.each { |e| e.clone!(oc) }
|
||||
oc.selected_distributor_payment_method_ids = (
|
||||
attachable_distributor_payment_methods.map(&:id) & selected_distributor_payment_method_ids
|
||||
)
|
||||
oc.selected_distributor_shipping_method_ids = (
|
||||
attachable_distributor_shipping_methods.map(&:id) & selected_distributor_shipping_method_ids
|
||||
)
|
||||
@@ -293,6 +297,18 @@ class OrderCycle < ApplicationRecord
|
||||
items.each { |li| scoper.scope(li.variant) }
|
||||
end
|
||||
|
||||
def distributor_payment_methods
|
||||
if simple? || selected_distributor_payment_methods.none?
|
||||
attachable_distributor_payment_methods
|
||||
else
|
||||
attachable_distributor_payment_methods.where(
|
||||
"distributors_payment_methods.id IN (?) OR distributor_id NOT IN (?)",
|
||||
selected_distributor_payment_methods.map(&:id),
|
||||
selected_distributor_payment_methods.map(&:distributor_id)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def distributor_shipping_methods
|
||||
if simple? || selected_distributor_shipping_methods.none?
|
||||
attachable_distributor_shipping_methods
|
||||
|
||||
@@ -20,6 +20,8 @@ module Spree
|
||||
|
||||
after_initialize :init
|
||||
|
||||
scope :inactive_or_backend, -> { where("active = false OR display_on = 'back_end'") }
|
||||
|
||||
scope :production, -> { where(environment: 'production') }
|
||||
|
||||
scope :managed_by, lambda { |user|
|
||||
@@ -57,6 +59,10 @@ module Spree
|
||||
Rails.application.config.spree.payment_methods
|
||||
end
|
||||
|
||||
def configured?
|
||||
!stripe? || stripe_configured?
|
||||
end
|
||||
|
||||
def provider_class
|
||||
raise 'You must implement provider_class method for this gateway.'
|
||||
end
|
||||
@@ -71,6 +77,10 @@ module Spree
|
||||
nil
|
||||
end
|
||||
|
||||
def frontend?
|
||||
active? && display_on != "back_end"
|
||||
end
|
||||
|
||||
# The class that will process payments for this payment type, used for @payment.source
|
||||
# e.g. CreditCard in the case of a the Gateway payment type
|
||||
# nil means the payment method doesn't require a source e.g. check
|
||||
@@ -120,5 +130,17 @@ module Spree
|
||||
def distributor_validation
|
||||
validates_with DistributorsValidator
|
||||
end
|
||||
|
||||
def stripe?
|
||||
type.ends_with?("StripeSCA")
|
||||
end
|
||||
|
||||
def stripe_configured?
|
||||
Spree::Config.stripe_connect_enabled &&
|
||||
Stripe.publishable_key &&
|
||||
preferred_enterprise_id.present? &&
|
||||
preferred_enterprise_id > 0 &&
|
||||
stripe_account_id.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
37
app/services/order_available_payment_methods.rb
Normal file
37
app/services/order_available_payment_methods.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderAvailablePaymentMethods
|
||||
attr_reader :order, :customer
|
||||
|
||||
delegate :distributor,
|
||||
:order_cycle,
|
||||
to: :order
|
||||
|
||||
def initialize(order, customer = nil)
|
||||
@order, @customer = order, customer
|
||||
end
|
||||
|
||||
def to_a
|
||||
return [] if distributor.blank?
|
||||
|
||||
payment_methods = payment_methods_before_tag_rules_applied
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(distributor,
|
||||
"FilterPaymentMethods", customer&.tag_list)
|
||||
applicator.filter!(payment_methods)
|
||||
|
||||
payment_methods.uniq
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def payment_methods_before_tag_rules_applied
|
||||
if order_cycle.nil? || order_cycle.simple?
|
||||
distributor.payment_methods
|
||||
else
|
||||
distributor.payment_methods.where(
|
||||
id: order_cycle.distributor_payment_methods.select(:payment_method_id)
|
||||
)
|
||||
end.available.select(&:configured?)
|
||||
end
|
||||
end
|
||||
@@ -12,6 +12,9 @@ class OrderCycleForm
|
||||
@user = user
|
||||
@permissions = OpenFoodNetwork::Permissions.new(user)
|
||||
@schedule_ids = order_cycle_params.delete(:schedule_ids)
|
||||
@selected_distributor_payment_method_ids = order_cycle_params.delete(
|
||||
:selected_distributor_payment_method_ids
|
||||
)
|
||||
@selected_distributor_shipping_method_ids = order_cycle_params.delete(
|
||||
:selected_distributor_shipping_method_ids
|
||||
)
|
||||
@@ -27,6 +30,7 @@ class OrderCycleForm
|
||||
order_cycle.schedule_ids = schedule_ids if parameter_specified?(:schedule_ids)
|
||||
order_cycle.save!
|
||||
apply_exchange_changes
|
||||
attach_selected_distributor_payment_methods
|
||||
attach_selected_distributor_shipping_methods
|
||||
sync_subscriptions
|
||||
true
|
||||
@@ -49,16 +53,29 @@ class OrderCycleForm
|
||||
return if exchanges_unchanged?
|
||||
|
||||
OpenFoodNetwork::OrderCycleFormApplicator.new(order_cycle, user).go!
|
||||
|
||||
# reload so outgoing exchanges are up-to-date for shipping/payment method validations
|
||||
order_cycle.reload
|
||||
end
|
||||
|
||||
def attach_selected_distributor_payment_methods
|
||||
return if @selected_distributor_payment_method_ids.nil?
|
||||
|
||||
order_cycle.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
|
||||
order_cycle.save!
|
||||
end
|
||||
|
||||
def attach_selected_distributor_shipping_methods
|
||||
return if @selected_distributor_shipping_method_ids.nil?
|
||||
|
||||
order_cycle.reload # so outgoing exchanges are up-to-date for shipping method validations
|
||||
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
|
||||
order_cycle.save!
|
||||
end
|
||||
|
||||
def attachable_distributor_payment_method_ids
|
||||
@attachable_distributor_payment_method_ids ||= order_cycle.attachable_distributor_payment_methods.map(&:id)
|
||||
end
|
||||
|
||||
def attachable_distributor_shipping_method_ids
|
||||
@attachable_distributor_shipping_method_ids ||= order_cycle.attachable_distributor_shipping_methods.map(&:id)
|
||||
end
|
||||
@@ -69,6 +86,19 @@ class OrderCycleForm
|
||||
end
|
||||
end
|
||||
|
||||
def selected_distributor_payment_method_ids
|
||||
@selected_distributor_payment_method_ids = (
|
||||
attachable_distributor_payment_method_ids &
|
||||
@selected_distributor_payment_method_ids.reject(&:blank?).map(&:to_i)
|
||||
)
|
||||
|
||||
if attachable_distributor_payment_method_ids.sort == @selected_distributor_payment_method_ids.sort
|
||||
@selected_distributor_payment_method_ids = []
|
||||
end
|
||||
|
||||
@selected_distributor_payment_method_ids
|
||||
end
|
||||
|
||||
def selected_distributor_shipping_method_ids
|
||||
@selected_distributor_shipping_method_ids = (
|
||||
attachable_distributor_shipping_method_ids &
|
||||
|
||||
@@ -17,7 +17,8 @@ module PermittedAttributes
|
||||
:name, :orders_open_at, :orders_close_at, :coordinator_id,
|
||||
:preferred_product_selection_from_coordinator_inventory_only,
|
||||
:automatic_notifications,
|
||||
{ schedule_ids: [], selected_distributor_shipping_method_ids: [], coordinator_fee_ids: [] }
|
||||
{ schedule_ids: [], selected_distributor_payment_method_ids: [],
|
||||
selected_distributor_shipping_method_ids: [], coordinator_fee_ids: [] }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
%fieldset.no-border-bottom
|
||||
%legend{ align: 'center'}= t('.checkout_options')
|
||||
|
||||
= hidden_field_tag "order_cycle[selected_distributor_shipping_method_ids][]", ""
|
||||
|
||||
.row
|
||||
.three.columns
|
||||
|
||||
@@ -19,10 +17,12 @@
|
||||
%table.checkout-options
|
||||
%thead
|
||||
%tr
|
||||
%th{ colspan: 2 }= t('.shipping_methods')
|
||||
%th{ colspan: 2 }
|
||||
= t('.shipping_methods')
|
||||
= hidden_field_tag "order_cycle[selected_distributor_shipping_method_ids][]", ""
|
||||
- @order_cycle.distributors.each do |distributor|
|
||||
- distributor_shipping_methods = @order_cycle.attachable_distributor_shipping_methods.where("distributor_id = ?", distributor.id).includes(:shipping_method)
|
||||
%tr{ "data-controller": "select-all" }
|
||||
%tr{ class: "distributor-#{distributor.id}-shipping-methods", "data-controller": "select-all" }
|
||||
%td.text-center
|
||||
- if distributor_shipping_methods.many?
|
||||
%label
|
||||
@@ -48,17 +48,36 @@
|
||||
%p
|
||||
= t('.no_shipping_methods')
|
||||
%tr
|
||||
%th{ colspan: 2 }= t('.payment_methods')
|
||||
%tr
|
||||
%td
|
||||
%td
|
||||
- if @order_cycle.attachable_payment_methods.available(:both).any?
|
||||
%ul
|
||||
- @order_cycle.attachable_payment_methods.available(:both).each do |payment_method|
|
||||
%li= payment_method.name
|
||||
- else
|
||||
%p
|
||||
= t('.no_payment_methods')
|
||||
%th{ colspan: 2 }
|
||||
= t('.payment_methods')
|
||||
= hidden_field_tag "order_cycle[selected_distributor_payment_method_ids][]", ""
|
||||
- @order_cycle.distributors.each do |distributor|
|
||||
- distributor_payment_methods = @order_cycle.attachable_distributor_payment_methods.where("distributor_id = ?", distributor.id).includes(:payment_method)
|
||||
%tr{ class: "distributor-#{distributor.id}-payment-methods", "data-controller": "select-all" }
|
||||
%td.text-center
|
||||
- if distributor_payment_methods.many?
|
||||
%label
|
||||
= check_box_tag nil, nil, nil, { "data-action": "change->select-all#toggleAll", "data-select-all-target": "all" }
|
||||
= t(".select_all")
|
||||
%td
|
||||
%em= distributor.name
|
||||
- distributor_payment_methods.each do |distributor_payment_method|
|
||||
%p
|
||||
%label{ class: ("disabled" if distributor_payment_methods.one? || !distributor_payment_method.payment_method.frontend?) }
|
||||
= check_box_tag "order_cycle[selected_distributor_payment_method_ids][]",
|
||||
distributor_payment_method.id,
|
||||
@order_cycle.distributor_payment_methods.include?(distributor_payment_method),
|
||||
id: "order_cycle_selected_distributor_payment_method_ids_#{distributor_payment_method.id}",
|
||||
data: ({ "action" => "change->select-all#toggleCheckbox", "select-all-target" => "checkbox" } if distributor_payment_method.payment_method.frontend?)
|
||||
= distributor_payment_method.payment_method.name
|
||||
- distributor.payment_methods.inactive_or_backend.each do |payment_method|
|
||||
%label.disabled
|
||||
= check_box_tag nil, nil, false, disabled: true
|
||||
= payment_method.name
|
||||
= "(#{t('.back_end')})"
|
||||
- if distributor.payment_methods.available.none?
|
||||
%p
|
||||
= t('.no_payment_methods')
|
||||
|
||||
%div#save-bar
|
||||
%div.container
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module OpenFoodNetwork
|
||||
class AvailablePaymentMethodFilter
|
||||
def filter!(payment_methods)
|
||||
if stripe_enabled?
|
||||
payment_methods.to_a.reject! do |payment_method|
|
||||
payment_method.type.ends_with?("StripeSCA") &&
|
||||
stripe_configuration_incomplete?(payment_method)
|
||||
end
|
||||
else
|
||||
payment_methods.to_a.reject! do |payment_method|
|
||||
payment_method.type.ends_with?("StripeSCA")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stripe_enabled?
|
||||
Spree::Config.stripe_connect_enabled && Stripe.publishable_key
|
||||
end
|
||||
|
||||
def stripe_configuration_incomplete?(payment_method)
|
||||
payment_method.preferred_enterprise_id.nil? ||
|
||||
payment_method.preferred_enterprise_id.zero? ||
|
||||
payment_method.stripe_account_id.blank?
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,175 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe EnterprisesHelper, type: :helper do
|
||||
let(:user) { create(:user) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:some_other_distributor) { create(:distributor_enterprise) }
|
||||
|
||||
before { allow(helper).to receive(:spree_current_user) { user } }
|
||||
|
||||
describe "loading available payment methods" do
|
||||
let!(:pm1) { create(:payment_method, distributors: [distributor]) }
|
||||
let!(:pm2) { create(:payment_method, distributors: [some_other_distributor]) }
|
||||
|
||||
context "when the order has no current_distributor" do
|
||||
before do
|
||||
allow(helper).to receive(:current_distributor) { nil }
|
||||
end
|
||||
|
||||
it "returns an empty array" do
|
||||
expect(helper.available_payment_methods).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
context "when no tag rules are in effect" do
|
||||
before { allow(helper).to receive(:current_distributor) { distributor } }
|
||||
|
||||
it "finds the payment methods for the current distributor" do
|
||||
expect(helper.available_payment_methods).to_not include pm2
|
||||
expect(helper.available_payment_methods).to include pm1
|
||||
end
|
||||
end
|
||||
|
||||
context "when FilterPaymentMethods tag rules are in effect" do
|
||||
let(:customer) { create(:customer, user: user, enterprise: distributor) }
|
||||
let!(:tag_rule) {
|
||||
create(:filter_payment_methods_tag_rule,
|
||||
enterprise: distributor,
|
||||
preferred_customer_tags: "trusted",
|
||||
preferred_payment_method_tags: "trusted")
|
||||
}
|
||||
let!(:default_tag_rule) {
|
||||
create(:filter_payment_methods_tag_rule,
|
||||
enterprise: distributor,
|
||||
is_default: true,
|
||||
preferred_payment_method_tags: "trusted")
|
||||
}
|
||||
let(:tagged_pm) { pm1 }
|
||||
let(:untagged_pm) { pm2 }
|
||||
|
||||
before do
|
||||
tagged_pm.update_attribute(:tag_list, 'trusted')
|
||||
distributor.payment_methods = [tagged_pm, untagged_pm]
|
||||
allow(helper).to receive(:current_distributor) { distributor }
|
||||
end
|
||||
|
||||
context "with a preferred visiblity of 'visible', default visibility of 'hidden'" do
|
||||
before {
|
||||
tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, 'visible')
|
||||
}
|
||||
before {
|
||||
default_tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, 'hidden')
|
||||
}
|
||||
|
||||
context "when the customer is nil" do
|
||||
it "applies default action (hide)" do
|
||||
expect(helper.current_customer).to be nil
|
||||
expect(helper.available_payment_methods).to include untagged_pm
|
||||
expect(helper.available_payment_methods).to_not include tagged_pm
|
||||
end
|
||||
end
|
||||
|
||||
context "when the customer's tags match" do
|
||||
before { customer.update_attribute(:tag_list, 'trusted') }
|
||||
|
||||
it "applies the action (show)" do
|
||||
expect(helper.current_customer).to eq customer
|
||||
expect(helper.available_payment_methods).to include tagged_pm, untagged_pm
|
||||
end
|
||||
end
|
||||
|
||||
context "when the customer's tags don't match" do
|
||||
before { customer.update_attribute(:tag_list, 'something') }
|
||||
|
||||
it "applies the default action (hide)" do
|
||||
expect(helper.current_customer).to eq customer
|
||||
expect(helper.available_payment_methods).to include untagged_pm
|
||||
expect(helper.available_payment_methods).to_not include tagged_pm
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with a preferred visiblity of 'hidden', default visibility of 'visible'" do
|
||||
before {
|
||||
tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, 'hidden')
|
||||
}
|
||||
before {
|
||||
default_tag_rule.update_attribute(:preferred_matched_payment_methods_visibility,
|
||||
'visible')
|
||||
}
|
||||
|
||||
context "when the customer is nil" do
|
||||
it "applies default action (show)" do
|
||||
expect(helper.current_customer).to be nil
|
||||
expect(helper.available_payment_methods).to include tagged_pm, untagged_pm
|
||||
end
|
||||
end
|
||||
|
||||
context "when the customer's tags match" do
|
||||
before { customer.update_attribute(:tag_list, 'trusted') }
|
||||
|
||||
it "applies the action (hide)" do
|
||||
expect(helper.current_customer).to eq customer
|
||||
expect(helper.available_payment_methods).to include untagged_pm
|
||||
expect(helper.available_payment_methods).to_not include tagged_pm
|
||||
end
|
||||
end
|
||||
|
||||
context "when the customer's tags don't match" do
|
||||
before { customer.update_attribute(:tag_list, 'something') }
|
||||
|
||||
it "applies the default action (show)" do
|
||||
expect(helper.current_customer).to eq customer
|
||||
expect(helper.available_payment_methods).to include tagged_pm, untagged_pm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when Stripe payment methods are present" do
|
||||
let!(:pm3) {
|
||||
create(:stripe_sca_payment_method, distributors: [distributor],
|
||||
preferred_enterprise_id: distributor.id)
|
||||
}
|
||||
let!(:pm4) {
|
||||
create(:stripe_sca_payment_method, distributors: [distributor],
|
||||
preferred_enterprise_id: some_other_distributor.id)
|
||||
}
|
||||
let(:available_payment_methods) { helper.available_payment_methods }
|
||||
|
||||
around do |example|
|
||||
original_stripe_connect_enabled = Spree::Config[:stripe_connect_enabled]
|
||||
example.run
|
||||
Spree::Config.set(stripe_connect_enabled: original_stripe_connect_enabled)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_distributor) { distributor }
|
||||
end
|
||||
|
||||
context "and Stripe Connect is disabled" do
|
||||
before { Spree::Config.set(stripe_connect_enabled: false) }
|
||||
|
||||
it "ignores Stripe payment methods" do
|
||||
expect(available_payment_methods).to_not include pm3, pm4
|
||||
end
|
||||
end
|
||||
|
||||
context "and Stripe Connect is enabled" do
|
||||
let!(:stripe_account) { create(:stripe_account, enterprise_id: distributor.id) }
|
||||
|
||||
before do
|
||||
Spree::Config.set(stripe_connect_enabled: true)
|
||||
Stripe.publishable_key = "some_key"
|
||||
end
|
||||
|
||||
it "includes Stripe payment methods with a valid stripe accounts" do
|
||||
expect(available_payment_methods).to include pm3
|
||||
expect(available_payment_methods).to_not include pm4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -276,7 +276,7 @@ describe Enterprise do
|
||||
expect(Enterprise.ready_for_checkout).not_to include e
|
||||
end
|
||||
|
||||
it "does not show enterprises wchich only have backend shipping methods" do
|
||||
it "does not show enterprises which only have backend shipping methods" do
|
||||
create(:shipping_method, distributors: [e],
|
||||
display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end])
|
||||
create(:payment_method, distributors: [e])
|
||||
@@ -354,6 +354,13 @@ describe Enterprise do
|
||||
create(:payment_method, distributors: [e])
|
||||
expect(e.reload).to be_ready_for_checkout
|
||||
end
|
||||
|
||||
it "returns false for enterprises with payment methods that are available but not configured
|
||||
correctly" do
|
||||
create(:shipping_method, distributors: [e])
|
||||
create(:stripe_sca_payment_method, distributors: [e])
|
||||
expect(e.reload).not_to be_ready_for_checkout
|
||||
end
|
||||
end
|
||||
|
||||
describe "distributors_with_active_order_cycles" do
|
||||
|
||||
@@ -404,7 +404,32 @@ describe OrderCycle do
|
||||
expect(cloned_exchange_attributes).to match_array original_exchange_attributes
|
||||
end
|
||||
|
||||
context "when it has preferred shipping methods which can longer be applied validly
|
||||
context "when it has selected payment methods which can longer be applied validly
|
||||
e.g. payment method is backoffice only" do
|
||||
it "only attaches the valid ones to the clone" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
distributor_payment_method_i = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
distributor_payment_method_ii = create(
|
||||
:payment_method,
|
||||
distributors: [distributor],
|
||||
display_on: "back_end"
|
||||
).distributor_payment_methods.first
|
||||
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
|
||||
order_cycle.selected_distributor_payment_methods = [
|
||||
distributor_payment_method_i,
|
||||
distributor_payment_method_ii
|
||||
]
|
||||
|
||||
cloned_order_cycle = order_cycle.clone!
|
||||
|
||||
expect(cloned_order_cycle.distributor_payment_methods).to eq [distributor_payment_method_i]
|
||||
end
|
||||
end
|
||||
|
||||
context "when it has selected shipping methods which can longer be applied validly
|
||||
e.g. shipping method is backoffice only" do
|
||||
it "only attaches the valid ones to the clone" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
@@ -637,6 +662,32 @@ describe OrderCycle do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#attachable_distributor_payment_methods" do
|
||||
it "includes distributor payment methods from the distributors on the order cycle" do
|
||||
payment_method = create(:payment_method)
|
||||
oc = create(:simple_order_cycle, distributors: [payment_method.distributors.first])
|
||||
distributor_payment_method = payment_method.distributor_payment_methods.first
|
||||
|
||||
expect(oc.attachable_distributor_payment_methods).to eq([distributor_payment_method])
|
||||
end
|
||||
|
||||
it "does not include backoffice only distributor payment methods" do
|
||||
payment_method = create(:payment_method, display_on: "back_end")
|
||||
enterprise = create(:enterprise, payment_methods: [payment_method])
|
||||
oc = create(:simple_order_cycle, distributors: [enterprise])
|
||||
|
||||
expect(oc.attachable_distributor_payment_methods).to be_empty
|
||||
end
|
||||
|
||||
it "does not include inactive distributor payment methods" do
|
||||
payment_method = create(:payment_method, active: false)
|
||||
enterprise = create(:enterprise, payment_methods: [payment_method])
|
||||
oc = create(:simple_order_cycle, distributors: [enterprise])
|
||||
|
||||
expect(oc.attachable_distributor_payment_methods).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe "#attachable_distributor_shipping_methods" do
|
||||
it "includes distributor shipping methods from the distributors on the order cycle" do
|
||||
shipping_method = create(:shipping_method)
|
||||
@@ -655,6 +706,80 @@ describe OrderCycle do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#distributor_payment_methods" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
it "returns all attachable distributor payment methods if the order cycle is simple" do
|
||||
oc = create(:sells_own_order_cycle, distributors: [distributor])
|
||||
|
||||
distributor_payment_method = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
|
||||
expect(oc.distributor_payment_methods).to eq [distributor_payment_method]
|
||||
end
|
||||
|
||||
context "distributor order cycle i.e. non-simple" do
|
||||
let(:oc) { create(:distributor_order_cycle, distributors: [distributor]) }
|
||||
|
||||
it "returns all attachable distributor payment methods if no distributor payment methods
|
||||
have been selected specifically" do
|
||||
distributor_payment_method = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
|
||||
expect(oc.selected_distributor_payment_methods).to be_empty
|
||||
expect(oc.distributor_payment_methods).to eq [distributor_payment_method]
|
||||
end
|
||||
|
||||
it "returns selected distributor payment methods if they have been specified" do
|
||||
distributor_payment_method_i = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
distributor_payment_method_ii = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
|
||||
oc.selected_distributor_payment_methods << distributor_payment_method_ii
|
||||
|
||||
expect(oc.distributor_payment_methods).to eq [distributor_payment_method_ii]
|
||||
end
|
||||
|
||||
context "with multiple distributors" do
|
||||
let(:other_distributor) { create(:distributor_enterprise) }
|
||||
let(:oc) { create(:distributor_order_cycle, distributors: [distributor, other_distributor]) }
|
||||
|
||||
it "returns all attachable distributor payment methods for a distributor if no distributor
|
||||
payment methods have been selected specifically for that distributor, even if
|
||||
distributor payment methods have been selected specifically for a different distributor
|
||||
on the order cycle" do
|
||||
distributor_payment_method = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
other_distributor_payment_method_i = create(
|
||||
:payment_method,
|
||||
distributors: [other_distributor]
|
||||
).distributor_payment_methods.first
|
||||
other_distributor_payment_method_ii = create(
|
||||
:payment_method,
|
||||
distributors: [other_distributor]
|
||||
).distributor_payment_methods.first
|
||||
oc.selected_distributor_payment_methods << other_distributor_payment_method_i
|
||||
|
||||
expect(oc.distributor_payment_methods).to eq [
|
||||
distributor_payment_method,
|
||||
other_distributor_payment_method_i
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#distributor_shipping_methods" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
|
||||
@@ -5,100 +5,166 @@ require 'spec_helper'
|
||||
class Spree::Gateway::Test < Spree::Gateway
|
||||
end
|
||||
|
||||
module Spree
|
||||
describe PaymentMethod do
|
||||
describe "#available" do
|
||||
let(:enterprise) { create(:enterprise) }
|
||||
describe Spree::PaymentMethod do
|
||||
describe "#available" do
|
||||
let(:enterprise) { create(:enterprise) }
|
||||
|
||||
before do
|
||||
Spree::PaymentMethod.delete_all
|
||||
|
||||
[nil, 'both', 'back_end'].each do |display_on|
|
||||
Spree::Gateway::Test.create(
|
||||
name: 'Display Both',
|
||||
display_on: display_on,
|
||||
active: true,
|
||||
environment: 'test',
|
||||
description: 'foofah',
|
||||
distributors: [enterprise]
|
||||
)
|
||||
end
|
||||
expect(Spree::PaymentMethod.all.size).to eq 3
|
||||
end
|
||||
|
||||
it "should return all methods available to front-end/back-end when no parameter is passed" do
|
||||
expect(Spree::PaymentMethod.available.size).to eq 2
|
||||
end
|
||||
|
||||
it "should return all methods available to front-end/back-end when display_on = :both" do
|
||||
expect(Spree::PaymentMethod.available(:both).size).to eq 2
|
||||
end
|
||||
|
||||
it "should return all methods available to back-end when display_on = :back_end" do
|
||||
expect(Spree::PaymentMethod.available(:back_end).size).to eq 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "#configured?" do
|
||||
context "non-Stripe payment method" do
|
||||
let(:payment_method) { build(:payment_method) }
|
||||
|
||||
it "returns true" do
|
||||
expect(payment_method).to be_configured
|
||||
end
|
||||
end
|
||||
|
||||
context "Stripe payment method" do
|
||||
let(:payment_method) { create(:stripe_sca_payment_method) }
|
||||
|
||||
around do |example|
|
||||
original_stripe_connect_enabled = Spree::Config[:stripe_connect_enabled]
|
||||
example.run
|
||||
Spree::Config.set(stripe_connect_enabled: original_stripe_connect_enabled)
|
||||
end
|
||||
|
||||
before do
|
||||
Spree::PaymentMethod.delete_all
|
||||
Spree::Config.set(stripe_connect_enabled: true)
|
||||
Stripe.publishable_key = "some_key"
|
||||
end
|
||||
|
||||
[nil, 'both', 'back_end'].each do |display_on|
|
||||
Spree::Gateway::Test.create(
|
||||
name: 'Display Both',
|
||||
display_on: display_on,
|
||||
active: true,
|
||||
environment: 'test',
|
||||
description: 'foofah',
|
||||
distributors: [enterprise]
|
||||
)
|
||||
context "and Stripe Connect is enabled and a Stripe publishable key, account id, account
|
||||
owner are all present" do
|
||||
it "returns true" do
|
||||
expect(payment_method).to be_configured
|
||||
end
|
||||
expect(Spree::PaymentMethod.all.size).to eq 3
|
||||
end
|
||||
|
||||
it "should return all methods available to front-end/back-end when no parameter is passed" do
|
||||
expect(Spree::PaymentMethod.available.size).to eq 2
|
||||
context "and Stripe Connect is disabled" do
|
||||
before { Spree::Config.set(stripe_connect_enabled: false) }
|
||||
|
||||
it "returns false" do
|
||||
expect(payment_method).not_to be_configured
|
||||
end
|
||||
end
|
||||
|
||||
it "should return all methods available to front-end/back-end when display_on = :both" do
|
||||
expect(Spree::PaymentMethod.available(:both).size).to eq 2
|
||||
context "and a Stripe publishable key is not present" do
|
||||
before { Spree::Config.set(stripe_connect_enabled: false) }
|
||||
|
||||
it "returns false" do
|
||||
expect(payment_method).not_to be_configured
|
||||
end
|
||||
end
|
||||
|
||||
it "should return all methods available to back-end when display_on = :back_end" do
|
||||
expect(Spree::PaymentMethod.available(:back_end).size).to eq 2
|
||||
context "and a Stripe account owner is not present" do
|
||||
before { payment_method.preferred_enterprise_id = nil }
|
||||
|
||||
it "returns false" do
|
||||
expect(payment_method).not_to be_configured
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "orders payment methods by name" do
|
||||
pm1 = create(:payment_method, name: 'ZZ')
|
||||
pm2 = create(:payment_method, name: 'AA')
|
||||
pm3 = create(:payment_method, name: 'BB')
|
||||
context "and a Stripe account ID is not present" do
|
||||
before do
|
||||
StripeAccount.find_by(
|
||||
enterprise_id: payment_method.preferred_enterprise_id
|
||||
).update_column(:stripe_user_id, nil)
|
||||
end
|
||||
|
||||
expect(PaymentMethod.by_name).to eq([pm2, pm3, pm1])
|
||||
end
|
||||
|
||||
it "raises errors when required fields are missing" do
|
||||
pm = PaymentMethod.new
|
||||
pm.save
|
||||
expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"])
|
||||
end
|
||||
|
||||
it "generates a clean name for known Payment Method types" do
|
||||
expect(Spree::PaymentMethod::Check.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.check"))
|
||||
expect(Spree::Gateway::PayPalExpress.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.paypalexpress"))
|
||||
expect(Spree::Gateway::StripeSCA.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.stripesca"))
|
||||
expect(Spree::Gateway::BogusSimple.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogussimple"))
|
||||
expect(Spree::Gateway::Bogus.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogus"))
|
||||
end
|
||||
|
||||
it "computes the amount of fees" do
|
||||
order = create(:order)
|
||||
|
||||
free_payment_method = create(:payment_method) # flat rate calculator with preferred_amount of 0
|
||||
expect(free_payment_method.compute_amount(order)).to eq 0
|
||||
|
||||
flat_rate_payment_method = create(:payment_method,
|
||||
calculator: ::Calculator::FlatRate.new(preferred_amount: 10))
|
||||
expect(flat_rate_payment_method.compute_amount(order)).to eq 10
|
||||
|
||||
flat_percent_payment_method = create(:payment_method,
|
||||
calculator: ::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10))
|
||||
expect(flat_percent_payment_method.compute_amount(order)).to eq 0
|
||||
|
||||
product = create(:product)
|
||||
order.contents.add(product.variants.first)
|
||||
expect(flat_percent_payment_method.compute_amount(order)).to eq 2.0
|
||||
end
|
||||
|
||||
describe "scope" do
|
||||
describe "filtering to specified distributors" do
|
||||
let!(:distributor_a) { create(:distributor_enterprise) }
|
||||
let!(:distributor_b) { create(:distributor_enterprise) }
|
||||
let!(:distributor_c) { create(:distributor_enterprise) }
|
||||
|
||||
let!(:payment_method_a) {
|
||||
create(:payment_method, distributors: [distributor_a, distributor_b])
|
||||
}
|
||||
let!(:payment_method_b) { create(:payment_method, distributors: [distributor_b]) }
|
||||
let!(:payment_method_c) { create(:payment_method, distributors: [distributor_c]) }
|
||||
|
||||
it "includes only unique records under specified distributors" do
|
||||
result = described_class.for_distributors([distributor_a, distributor_b])
|
||||
expect(result.length).to eq(2)
|
||||
expect(result).to include(payment_method_a)
|
||||
expect(result).to include(payment_method_b)
|
||||
it "returns false" do
|
||||
expect(payment_method).not_to be_configured
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "orders payment methods by name" do
|
||||
pm1 = create(:payment_method, name: 'ZZ')
|
||||
pm2 = create(:payment_method, name: 'AA')
|
||||
pm3 = create(:payment_method, name: 'BB')
|
||||
|
||||
expect(Spree::PaymentMethod.by_name).to eq([pm2, pm3, pm1])
|
||||
end
|
||||
|
||||
it "raises errors when required fields are missing" do
|
||||
pm = Spree::PaymentMethod.new
|
||||
pm.save
|
||||
expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"])
|
||||
end
|
||||
|
||||
it "generates a clean name for known Payment Method types" do
|
||||
expect(Spree::PaymentMethod::Check.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.check"))
|
||||
expect(Spree::Gateway::PayPalExpress.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.paypalexpress"))
|
||||
expect(Spree::Gateway::StripeSCA.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.stripesca"))
|
||||
expect(Spree::Gateway::BogusSimple.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogussimple"))
|
||||
expect(Spree::Gateway::Bogus.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogus"))
|
||||
end
|
||||
|
||||
it "computes the amount of fees" do
|
||||
order = create(:order)
|
||||
|
||||
free_payment_method = create(:payment_method) # flat rate calculator with preferred_amount of 0
|
||||
expect(free_payment_method.compute_amount(order)).to eq 0
|
||||
|
||||
flat_rate_payment_method = create(:payment_method,
|
||||
calculator: ::Calculator::FlatRate.new(preferred_amount: 10))
|
||||
expect(flat_rate_payment_method.compute_amount(order)).to eq 10
|
||||
|
||||
flat_percent_payment_method = create(:payment_method,
|
||||
calculator: ::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10))
|
||||
expect(flat_percent_payment_method.compute_amount(order)).to eq 0
|
||||
|
||||
product = create(:product)
|
||||
order.contents.add(product.variants.first)
|
||||
expect(flat_percent_payment_method.compute_amount(order)).to eq 2.0
|
||||
end
|
||||
|
||||
describe "scope" do
|
||||
describe "filtering to specified distributors" do
|
||||
let!(:distributor_a) { create(:distributor_enterprise) }
|
||||
let!(:distributor_b) { create(:distributor_enterprise) }
|
||||
let!(:distributor_c) { create(:distributor_enterprise) }
|
||||
|
||||
let!(:payment_method_a) {
|
||||
create(:payment_method, distributors: [distributor_a, distributor_b])
|
||||
}
|
||||
let!(:payment_method_b) { create(:payment_method, distributors: [distributor_b]) }
|
||||
let!(:payment_method_c) { create(:payment_method, distributors: [distributor_c]) }
|
||||
|
||||
it "includes only unique records under specified distributors" do
|
||||
result = described_class.for_distributors([distributor_a, distributor_b])
|
||||
expect(result.length).to eq(2)
|
||||
expect(result).to include(payment_method_a)
|
||||
expect(result).to include(payment_method_b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -82,11 +82,18 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques
|
||||
}
|
||||
end
|
||||
|
||||
around do |example|
|
||||
original_stripe_connect_enabled = Spree::Config[:stripe_connect_enabled]
|
||||
example.run
|
||||
Spree::Config.set(stripe_connect_enabled: original_stripe_connect_enabled)
|
||||
end
|
||||
|
||||
before do
|
||||
order_cycle_distributed_variants = double(:order_cycle_distributed_variants)
|
||||
allow(OrderCycleDistributedVariants).to receive(:new) { order_cycle_distributed_variants }
|
||||
allow(order_cycle_distributed_variants).to receive(:distributes_order_variants?) { true }
|
||||
|
||||
allow(Stripe).to receive(:publishable_key).and_return("some_token")
|
||||
Spree::Config.set(stripe_connect_enabled: true)
|
||||
Stripe.api_key = "sk_test_12345"
|
||||
order.update(distributor_id: enterprise.id, order_cycle_id: order_cycle.id)
|
||||
order.reload.update_totals
|
||||
|
||||
217
spec/services/order_available_payment_methods_spec.rb
Normal file
217
spec/services/order_available_payment_methods_spec.rb
Normal file
@@ -0,0 +1,217 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe OrderAvailablePaymentMethods do
|
||||
context "when the order has no current_distributor" do
|
||||
it "returns an empty array" do
|
||||
order_cycle = create(:sells_own_order_cycle)
|
||||
order = build(:order, distributor: nil, order_cycle: order_cycle)
|
||||
|
||||
expect(OrderAvailablePaymentMethods.new(order).to_a).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
it "does not return 'back office only' payment method" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
frontend_payment_method = create(:payment_method, distributors: [distributor])
|
||||
backoffice_only_payment_method = create(:payment_method,
|
||||
distributors: [distributor],
|
||||
display_on: 'back_end')
|
||||
order_cycle = create(:sells_own_order_cycle)
|
||||
order = build(:order, distributor: distributor, order_cycle: order_cycle)
|
||||
|
||||
available_payment_methods = OrderAvailablePaymentMethods.new(order).to_a
|
||||
|
||||
expect(available_payment_methods).to eq [frontend_payment_method]
|
||||
end
|
||||
|
||||
it "does not return payment methods which are not configured correctly" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
frontend_payment_method = create(:payment_method, distributors: [distributor])
|
||||
unconfigured_payment_method = create(:stripe_sca_payment_method,
|
||||
distributors: [distributor],
|
||||
display_on: 'back_end')
|
||||
order_cycle = create(:sells_own_order_cycle)
|
||||
order = build(:order, distributor: distributor, order_cycle: order_cycle)
|
||||
|
||||
available_payment_methods = OrderAvailablePaymentMethods.new(order).to_a
|
||||
|
||||
expect(available_payment_methods).to eq [frontend_payment_method]
|
||||
end
|
||||
|
||||
context "when no tag rules are in effect" do
|
||||
context "sells own order cycle i.e. simple" do
|
||||
it "only returns the payment methods which are available on the order cycle
|
||||
and belong to the order distributor" do
|
||||
distributor_i = create(:distributor_enterprise)
|
||||
distributor_ii = create(:distributor_enterprise)
|
||||
distributor_iii = create(:distributor_enterprise)
|
||||
payment_method_i = create(:payment_method, distributors: [distributor_i])
|
||||
payment_method_ii = create(:payment_method, distributors: [distributor_ii])
|
||||
payment_method_iii = create(:payment_method, distributors: [distributor_iii])
|
||||
order_cycle = create(:sells_own_order_cycle, distributors: [distributor_i, distributor_ii])
|
||||
order = build(:order, distributor: distributor_i, order_cycle: order_cycle)
|
||||
|
||||
available_payment_methods = OrderAvailablePaymentMethods.new(order).to_a
|
||||
|
||||
expect(available_payment_methods).to eq [payment_method_i]
|
||||
end
|
||||
end
|
||||
|
||||
context "distributor order cycle i.e. not simple" do
|
||||
it "only returns the payment methods which are available on the order cycle
|
||||
and belong to the order distributor" do
|
||||
distributor_i = create(:distributor_enterprise, payment_methods: [])
|
||||
distributor_ii = create(:distributor_enterprise, payment_methods: [])
|
||||
payment_method_i = create(:payment_method, distributors: [distributor_i])
|
||||
payment_method_ii = create(:payment_method, distributors: [distributor_i])
|
||||
payment_method_iii = create(:payment_method, distributors: [distributor_ii])
|
||||
payment_method_iv = create(:payment_method, distributors: [distributor_ii])
|
||||
order_cycle = create(:distributor_order_cycle,
|
||||
distributors: [distributor_i, distributor_ii])
|
||||
order_cycle.selected_distributor_payment_methods << [
|
||||
distributor_i.distributor_payment_methods.first,
|
||||
distributor_ii.distributor_payment_methods.first,
|
||||
]
|
||||
order = build(:order, distributor: distributor_i, order_cycle: order_cycle)
|
||||
|
||||
available_payment_methods = OrderAvailablePaymentMethods.new(order).to_a
|
||||
|
||||
expect(available_payment_methods).to eq [payment_method_i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when FilterPaymentMethods tag rules are in effect" do
|
||||
let(:user) { create(:user) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:other_distributor) { create(:distributor_enterprise) }
|
||||
let!(:distributor_payment_method) { create(:payment_method, distributors: [distributor]) }
|
||||
let!(:other_distributor_payment_method) do
|
||||
create(:payment_method, distributors: [other_distributor])
|
||||
end
|
||||
let(:customer) { create(:customer, user: user, enterprise: distributor) }
|
||||
let!(:tag_rule) {
|
||||
create(:filter_payment_methods_tag_rule,
|
||||
enterprise: distributor,
|
||||
preferred_customer_tags: "local",
|
||||
preferred_payment_method_tags: "local-delivery")
|
||||
}
|
||||
let!(:default_tag_rule) {
|
||||
create(:filter_payment_methods_tag_rule,
|
||||
enterprise: distributor,
|
||||
is_default: true,
|
||||
preferred_payment_method_tags: "local-delivery")
|
||||
}
|
||||
let!(:tagged_payment_method) { distributor_payment_method }
|
||||
let!(:untagged_payment_method) { other_distributor_payment_method }
|
||||
|
||||
before do
|
||||
tagged_payment_method.update_attribute(:tag_list, 'local-delivery')
|
||||
distributor.payment_methods = [tagged_payment_method, untagged_payment_method]
|
||||
end
|
||||
|
||||
context "with a preferred visiblity of 'visible', default visibility of 'hidden'" do
|
||||
before {
|
||||
tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, 'visible')
|
||||
}
|
||||
before {
|
||||
default_tag_rule.update_attribute(:preferred_matched_payment_methods_visibility,
|
||||
'hidden')
|
||||
}
|
||||
|
||||
let(:order_cycle) { create(:sells_own_order_cycle) }
|
||||
let(:order) { build(:order, distributor: distributor, order_cycle: order_cycle) }
|
||||
|
||||
context "when the customer is nil" do
|
||||
let(:available_payment_methods) { OrderAvailablePaymentMethods.new(order).to_a }
|
||||
|
||||
it "applies default action (hide)" do
|
||||
expect(available_payment_methods).to include untagged_payment_method
|
||||
expect(available_payment_methods).to_not include tagged_payment_method
|
||||
end
|
||||
end
|
||||
|
||||
context "when a customer is present" do
|
||||
let(:available_payment_methods) { OrderAvailablePaymentMethods.new(order, customer).to_a }
|
||||
|
||||
context "and the customer's tags match" do
|
||||
before do
|
||||
customer.update_attribute(:tag_list, 'local')
|
||||
end
|
||||
|
||||
it "applies the action (show)" do
|
||||
expect(available_payment_methods).to include(
|
||||
tagged_payment_method,
|
||||
untagged_payment_method
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "and the customer's tags don't match" do
|
||||
before do
|
||||
customer.update_attribute(:tag_list, 'something')
|
||||
end
|
||||
|
||||
it "applies the default action (hide)" do
|
||||
expect(available_payment_methods).to include untagged_payment_method
|
||||
expect(available_payment_methods).to_not include tagged_payment_method
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with a preferred visiblity of 'hidden', default visibility of 'visible'" do
|
||||
before {
|
||||
tag_rule.update_attribute(:preferred_matched_payment_methods_visibility, 'hidden')
|
||||
}
|
||||
before {
|
||||
default_tag_rule.update_attribute(:preferred_matched_payment_methods_visibility,
|
||||
'visible')
|
||||
}
|
||||
|
||||
let(:order_cycle) { create(:sells_own_order_cycle) }
|
||||
let(:order) { build(:order, distributor: distributor, order_cycle: order_cycle) }
|
||||
|
||||
context "when the customer is nil" do
|
||||
let(:available_payment_methods) { OrderAvailablePaymentMethods.new(order).to_a }
|
||||
|
||||
it "applies default action (show)" do
|
||||
expect(available_payment_methods).to include(
|
||||
tagged_payment_method,
|
||||
untagged_payment_method
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when a customer is present" do
|
||||
let(:available_payment_methods) { OrderAvailablePaymentMethods.new(order, customer).to_a }
|
||||
|
||||
context "and the customer's tags match" do
|
||||
before do
|
||||
customer.update_attribute(:tag_list, 'local')
|
||||
end
|
||||
|
||||
it "applies the action (hide)" do
|
||||
expect(available_payment_methods).to include untagged_payment_method
|
||||
expect(available_payment_methods).to_not include tagged_payment_method
|
||||
end
|
||||
end
|
||||
|
||||
context "and the customer's tags don't match" do
|
||||
before do
|
||||
customer.update_attribute(:tag_list, 'something')
|
||||
end
|
||||
|
||||
it "applies the default action (show)" do
|
||||
expect(available_payment_methods).to include(
|
||||
tagged_payment_method,
|
||||
untagged_payment_method
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -135,7 +135,9 @@ describe OrderCycleForm do
|
||||
let(:distributor) { order_cycle.coordinator }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:user) { distributor.owner }
|
||||
let(:payment_method) { create(:payment_method, distributors: [distributor]) }
|
||||
let(:shipping_method) { create(:shipping_method, distributors: [distributor]) }
|
||||
let(:distributor_payment_method) { payment_method.distributor_payment_methods.first }
|
||||
let(:distributor_shipping_method) { shipping_method.distributor_shipping_methods.first }
|
||||
let(:variant) { create(:variant, product: create(:product, supplier: supplier)) }
|
||||
let(:params) { { name: 'Some new name' } }
|
||||
@@ -151,14 +153,14 @@ describe OrderCycleForm do
|
||||
}
|
||||
end
|
||||
|
||||
context "basic update i.e. without exchanges or shipping methods" do
|
||||
context "basic update i.e. without exchanges or payment/shipping methods" do
|
||||
it do
|
||||
expect(form.save).to be true
|
||||
expect(order_cycle.name).to eq 'Some new name'
|
||||
end
|
||||
end
|
||||
|
||||
context "updating basics, incoming exchanges, outcoming exchanges
|
||||
context "updating basics, incoming exchanges, outcoming exchanges, payment_methods
|
||||
and shipping methods simultaneously" do
|
||||
before do
|
||||
params.merge!(
|
||||
@@ -171,21 +173,31 @@ describe OrderCycleForm do
|
||||
enterprise_fee_ids: []
|
||||
}],
|
||||
outgoing_exchanges: [outgoing_exchange_params],
|
||||
selected_distributor_payment_method_ids: [distributor_payment_method.id],
|
||||
selected_distributor_shipping_method_ids: [distributor_shipping_method.id]
|
||||
)
|
||||
end
|
||||
|
||||
it "saves everything i.e. the basics, incoming and outgoing exchanges and shipping methods" do
|
||||
it "saves everything i.e. the basics, incoming and outgoing exchanges, payment methods and
|
||||
shipping methods" do
|
||||
expect(form.save).to be true
|
||||
expect(order_cycle.name).to eq 'Some new name'
|
||||
expect(order_cycle.cached_incoming_exchanges.count).to eq 1
|
||||
expect(order_cycle.cached_outgoing_exchanges.count).to eq 1
|
||||
expect(order_cycle.distributor_payment_methods).to eq [distributor_payment_method]
|
||||
expect(order_cycle.distributor_shipping_methods).to eq [distributor_shipping_method]
|
||||
end
|
||||
end
|
||||
|
||||
context "updating outgoing exchanges and shipping methods simultaneously but the shipping
|
||||
method doesn't belong to the new or any existing order cycle distributor" do
|
||||
context "updating outgoing exchanges and shipping methods simultaneously but the payment
|
||||
and shipping methods don't belong to the new or any existing order cycle
|
||||
distributor" do
|
||||
let(:other_distributor_payment_method) do
|
||||
create(
|
||||
:payment_method,
|
||||
distributors: [create(:distributor_enterprise)]
|
||||
).distributor_payment_methods.first
|
||||
end
|
||||
let(:other_distributor_shipping_method) do
|
||||
create(
|
||||
:shipping_method,
|
||||
@@ -196,6 +208,7 @@ describe OrderCycleForm do
|
||||
before do
|
||||
params.merge!(
|
||||
outgoing_exchanges: [outgoing_exchange_params],
|
||||
selected_distributor_payment_method_ids: [other_distributor_payment_method.id],
|
||||
selected_distributor_shipping_method_ids: [other_distributor_shipping_method.id]
|
||||
)
|
||||
end
|
||||
@@ -203,10 +216,59 @@ describe OrderCycleForm do
|
||||
it "saves the outgoing exchange but ignores the shipping method" do
|
||||
expect(form.save).to be true
|
||||
expect(order_cycle.distributors).to eq [distributor]
|
||||
expect(order_cycle.distributor_payment_methods).to be_empty
|
||||
expect(order_cycle.distributor_shipping_methods).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "updating payment methods" do
|
||||
context "and it's valid" do
|
||||
it "saves the changes" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
distributor_payment_method = create(
|
||||
:payment_method,
|
||||
distributors: [distributor]
|
||||
).distributor_payment_methods.first
|
||||
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
|
||||
|
||||
form = OrderCycleForm.new(
|
||||
order_cycle,
|
||||
{ selected_distributor_payment_method_ids: [distributor_payment_method.id] },
|
||||
order_cycle.coordinator
|
||||
)
|
||||
|
||||
expect(form.save).to be true
|
||||
expect(order_cycle.distributor_payment_methods).to eq [distributor_payment_method]
|
||||
end
|
||||
end
|
||||
|
||||
context "with a payment method which doesn't belong to any distributor on the order cycle" do
|
||||
it "ignores it" do
|
||||
distributor_i = create(:distributor_enterprise)
|
||||
distributor_ii = create(:distributor_enterprise)
|
||||
distributor_payment_method_i = create(
|
||||
:payment_method,
|
||||
distributors: [distributor_i]
|
||||
).distributor_payment_methods.first
|
||||
distributor_payment_method_ii = create(
|
||||
:payment_method,
|
||||
distributors: [distributor_ii]
|
||||
).distributor_payment_methods.first
|
||||
order_cycle = create(:distributor_order_cycle,
|
||||
distributors: [distributor_i])
|
||||
|
||||
form = OrderCycleForm.new(
|
||||
order_cycle,
|
||||
{ selected_distributor_payment_method_ids: [distributor_payment_method_ii.id] },
|
||||
order_cycle.coordinator
|
||||
)
|
||||
|
||||
expect(form.save).to be true
|
||||
expect(order_cycle.distributor_payment_methods).to eq [distributor_payment_method_i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "updating shipping methods" do
|
||||
context "and it's valid" do
|
||||
it "saves the changes" do
|
||||
|
||||
@@ -22,6 +22,8 @@ describe '
|
||||
let!(:distributor) {
|
||||
create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true)
|
||||
}
|
||||
let!(:payment_method_i) { distributor.payment_methods.first }
|
||||
let!(:payment_method_ii) { create(:payment_method, distributors: [distributor]) }
|
||||
let!(:shipping_method_i) { distributor.shipping_methods.first }
|
||||
let!(:shipping_method_ii) { create(:shipping_method, distributors: [distributor]) }
|
||||
let(:oc) { OrderCycle.last }
|
||||
@@ -44,6 +46,7 @@ describe '
|
||||
|
||||
shipping_method_i.update!(name: "Pickup - always available")
|
||||
shipping_method_ii.update!(name: "Delivery - sometimes available")
|
||||
payment_method_ii.update!(name: "Cash")
|
||||
end
|
||||
|
||||
it "creating an order cycle with full interface", js: true do
|
||||
@@ -68,6 +71,8 @@ describe '
|
||||
add_supplier_with_fees
|
||||
add_distributor_with_fees
|
||||
select_distributor_shipping_methods
|
||||
select_distributor_payment_methods
|
||||
click_button 'Save and Back to List'
|
||||
|
||||
expect_all_data_saved
|
||||
end
|
||||
@@ -161,22 +166,50 @@ describe '
|
||||
click_button 'Save and Next'
|
||||
end
|
||||
|
||||
def select_distributor_payment_methods
|
||||
within("tr.distributor-#{distributor.id}-payment-methods") do
|
||||
expect(page).to have_checked_field "Select all"
|
||||
|
||||
expect(page).to have_checked_field "Check"
|
||||
expect(page).to have_checked_field "Cash"
|
||||
|
||||
uncheck "Cash"
|
||||
|
||||
expect(page).to have_unchecked_field "Select all"
|
||||
|
||||
expect_checking_select_all_payment_methods_works
|
||||
expect_unchecking_select_all_payment_methods_works
|
||||
|
||||
# Our final selection:
|
||||
check "Check"
|
||||
end
|
||||
end
|
||||
|
||||
def select_distributor_shipping_methods
|
||||
expect(page).to have_checked_field "Select all"
|
||||
within("tr.distributor-#{distributor.id}-shipping-methods") do
|
||||
expect(page).to have_checked_field "Select all"
|
||||
|
||||
expect(page).to have_checked_field "Pickup - always available"
|
||||
expect(page).to have_checked_field "Delivery - sometimes available"
|
||||
expect(page).to have_checked_field "Pickup - always available"
|
||||
expect(page).to have_checked_field "Delivery - sometimes available"
|
||||
|
||||
uncheck "Delivery - sometimes available"
|
||||
uncheck "Delivery - sometimes available"
|
||||
|
||||
expect(page).to have_unchecked_field "Select all"
|
||||
expect(page).to have_unchecked_field "Select all"
|
||||
|
||||
expect_checking_select_all_shipping_methods_works
|
||||
expect_unchecking_select_all_shipping_methods_works
|
||||
expect_checking_select_all_shipping_methods_works
|
||||
expect_unchecking_select_all_shipping_methods_works
|
||||
|
||||
# Our final selection:
|
||||
check "Pickup - always available"
|
||||
click_button 'Save and Back to List'
|
||||
# Our final selection:
|
||||
check "Pickup - always available"
|
||||
end
|
||||
end
|
||||
|
||||
def expect_checking_select_all_payment_methods_works
|
||||
# Now test that the "Select all" input is doing what it's supposed to:
|
||||
check "Select all"
|
||||
|
||||
expect(page).to have_checked_field "Check"
|
||||
expect(page).to have_checked_field "Cash"
|
||||
end
|
||||
|
||||
def expect_checking_select_all_shipping_methods_works
|
||||
@@ -187,6 +220,13 @@ describe '
|
||||
expect(page).to have_checked_field "Delivery - sometimes available"
|
||||
end
|
||||
|
||||
def expect_unchecking_select_all_payment_methods_works
|
||||
uncheck "Select all"
|
||||
|
||||
expect(page).to have_unchecked_field "Check"
|
||||
expect(page).to have_unchecked_field "Cash"
|
||||
end
|
||||
|
||||
def expect_unchecking_select_all_shipping_methods_works
|
||||
uncheck "Select all"
|
||||
|
||||
@@ -208,6 +248,7 @@ describe '
|
||||
expect_receival_instructions_saved
|
||||
expect_pickup_time_and_instructions_saved
|
||||
expect_distributor_shipping_methods_saved
|
||||
expect_distributor_payment_methods_saved
|
||||
end
|
||||
|
||||
def expect_opening_and_closing_times_saved
|
||||
@@ -240,6 +281,10 @@ describe '
|
||||
expect(exchange.tag_list).to eq(['wholesale'])
|
||||
end
|
||||
|
||||
def expect_distributor_payment_methods_saved
|
||||
expect(oc.distributor_payment_methods).to eq(payment_method_i.distributor_payment_methods)
|
||||
end
|
||||
|
||||
def expect_distributor_shipping_methods_saved
|
||||
expect(oc.distributor_shipping_methods).to eq(shipping_method_i.distributor_shipping_methods)
|
||||
end
|
||||
|
||||
@@ -272,6 +272,8 @@ describe '
|
||||
|
||||
expect_shipping_methods_to_be_checked_for(distributor_managed)
|
||||
expect_shipping_methods_to_be_checked_for(distributor_permitted)
|
||||
expect_payment_methods_to_be_checked_for(distributor_managed)
|
||||
expect_payment_methods_to_be_checked_for(distributor_permitted)
|
||||
|
||||
click_button 'Save and Back to List'
|
||||
order_cycle = OrderCycle.find_by(name: 'My order cycle')
|
||||
@@ -286,6 +288,9 @@ describe '
|
||||
expect(order_cycle.distributor_shipping_methods).to match_array(
|
||||
order_cycle.attachable_distributor_shipping_methods
|
||||
)
|
||||
expect(order_cycle.distributor_payment_methods).to match_array(
|
||||
order_cycle.attachable_distributor_payment_methods
|
||||
)
|
||||
end
|
||||
|
||||
context "editing an order cycle" do
|
||||
@@ -724,6 +729,14 @@ describe '
|
||||
|
||||
private
|
||||
|
||||
def expect_payment_methods_to_be_checked_for(distributor)
|
||||
distributor.distributor_payment_method_ids.each do |distributor_payment_method_id|
|
||||
expect(page).to have_checked_field(
|
||||
"order_cycle_selected_distributor_payment_method_ids_#{distributor_payment_method_id}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def expect_shipping_methods_to_be_checked_for(distributor)
|
||||
distributor.distributor_shipping_method_ids.each do |distributor_shipping_method_id|
|
||||
expect(page).to have_checked_field(
|
||||
|
||||
Reference in New Issue
Block a user