diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 866fd94334..5812d2395c 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -2,10 +2,10 @@ module Admin class OrderCyclesController < Admin::ResourceController - include OrderCyclesHelper + include ::OrderCyclesHelper include PaperTrailLogging - prepend_before_action :set_order_cycle_id, only: [:incoming, :outgoing] + prepend_before_action :set_order_cycle_id, only: [:incoming, :outgoing, :checkout_options] before_action :load_data_for_index, only: :index before_action :require_coordinator, only: :new before_action :remove_protected_attrs, only: [:update] @@ -67,10 +67,12 @@ module Admin update_nil_subscription_line_items_price_estimate(@order_cycle) respond_to do |format| flash[:notice] = I18n.t(:order_cycles_update_notice) if params[:reloading] == '1' - format.html { redirect_back(fallback_location: root_path) } + format.html { redirect_to_after_update_path } format.json { render json: { success: true } } end - else + elsif request.format.html? + render :checkout_options + elsif request.format.json? render json: { errors: @order_cycle.errors.full_messages }, status: :unprocessable_entity end end @@ -190,6 +192,16 @@ module Admin end end + def redirect_to_after_update_path + if params[:context] == "checkout_options" && params[:save] + redirect_to main_app.admin_order_cycle_checkout_options_path(@order_cycle) + elsif params[:context] == "checkout_options" && params[:save_and_back_to_list] + redirect_to main_app.admin_order_cycles_path + else + redirect_back(fallback_location: root_path) + end + end + def require_coordinator @order_cycle.coordinator = permitted_coordinating_enterprises_for(@order_cycle).find_by(id: params[:coordinator_id]) diff --git a/app/helpers/admin/order_cycles_helper.rb b/app/helpers/admin/order_cycles_helper.rb new file mode 100644 index 0000000000..c046ded504 --- /dev/null +++ b/app/helpers/admin/order_cycles_helper.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Admin + module OrderCyclesHelper + def order_cycle_shared_payment_methods(order_cycle) + order_cycle.attachable_payment_methods.select do |payment_method| + (payment_method.distributor_ids & order_cycle.distributor_ids).many? + end + end + + def order_cycle_shared_shipping_methods(order_cycle) + order_cycle.attachable_shipping_methods.select do |shipping_method| + (shipping_method.distributor_ids & order_cycle.distributor_ids).many? + end + end + end +end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 86f1a14a54..84800086c9 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -156,6 +156,23 @@ 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 + end + + def attachable_shipping_methods + return Spree::ShippingMethod.none if simple? || !shipping_methods_customisable? + + Spree::ShippingMethod.frontend. + joins(:distributor_shipping_methods). + where("distributor_id IN (?)", distributor_ids). + distinct + end + def clone! oc = dup oc.name = I18n.t("models.order_cycle.cloned_order_cycle_name", order_cycle: oc.name) diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb index 2e9aec849f..63857559cd 100644 --- a/app/models/spree/ability.rb +++ b/app/models/spree/ability.rb @@ -243,7 +243,9 @@ module Spree end def add_order_cycle_management_abilities(user) - can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle| + can [ + :admin, :index, :read, :edit, :update, :incoming, :outgoing, :checkout_options + ], OrderCycle do |order_cycle| OrderCycle.visible_by(user).include? order_cycle end can [:admin, :index, :create], Schedule diff --git a/app/services/order_available_shipping_methods.rb b/app/services/order_available_shipping_methods.rb new file mode 100644 index 0000000000..3c815d19a0 --- /dev/null +++ b/app/services/order_available_shipping_methods.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class OrderAvailableShippingMethods < Struct.new(:order, :customer) + delegate :distributor, + :order_cycle, + to: :order + + def to_a + return [] if distributor.blank? + + shipping_methods = shipping_methods_before_tag_rules_applied + + applicator = OpenFoodNetwork::TagRuleApplicator.new(distributor, + "FilterShippingMethods", customer&.tag_list) + applicator.filter!(shipping_methods) + + shipping_methods.uniq + end + + private + + def shipping_methods_before_tag_rules_applied + if order_cycle.nil? || order_cycle.simple? + distributor.shipping_methods + else + distributor.shipping_methods.where(id: order_cycle.shipping_methods.select(:id)) + end.frontend.to_a + end +end diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb index dd74607168..97282acabf 100644 --- a/app/services/permitted_attributes/order_cycle.rb +++ b/app/services/permitted_attributes/order_cycle.rb @@ -17,7 +17,7 @@ module PermittedAttributes :name, :orders_open_at, :orders_close_at, :coordinator_id, :preferred_product_selection_from_coordinator_inventory_only, :automatic_notifications, - { schedule_ids: [], coordinator_fee_ids: [] } + { schedule_ids: [], shipping_method_ids: [], coordinator_fee_ids: [] } ] end diff --git a/app/views/admin/order_cycles/_wizard_progress.html.haml b/app/views/admin/order_cycles/_wizard_progress.html.haml index 3224324ca6..cc13adcebf 100644 --- a/app/views/admin/order_cycles/_wizard_progress.html.haml +++ b/app/views/admin/order_cycles/_wizard_progress.html.haml @@ -6,6 +6,8 @@ = t("admin.order_cycles.wizard_progress.incoming") %li = t("admin.order_cycles.wizard_progress.outgoing") + %li + = t("admin.order_cycles.wizard_progress.checkout_options") - else %li{ class: "#{'current' if action_name == 'edit'}" } %a{ href: main_app.edit_admin_order_cycle_path(@order_cycle) } @@ -16,3 +18,6 @@ %li{ class: "#{'current' if action_name == 'outgoing'}" } %a{ href: main_app.admin_order_cycle_outgoing_path(@order_cycle) } = t("admin.order_cycles.wizard_progress.outgoing") + %li{ class: "#{'current' if action_name == 'checkout_options'}" } + %a{ href: main_app.admin_order_cycle_checkout_options_path(@order_cycle) } + = t("admin.order_cycles.wizard_progress.checkout_options") diff --git a/app/views/admin/order_cycles/checkout_options.html.haml b/app/views/admin/order_cycles/checkout_options.html.haml new file mode 100644 index 0000000000..97f436308c --- /dev/null +++ b/app/views/admin/order_cycles/checkout_options.html.haml @@ -0,0 +1,83 @@ += render partial: "/admin/order_cycles/order_cycle_top_buttons" + +- content_for :page_title do + = t :edit_order_cycle + +- shared_payment_methods = order_cycle_shared_payment_methods(@order_cycle) +- shared_shipping_methods = order_cycle_shared_shipping_methods(@order_cycle) + += form_for [main_app, :admin, @order_cycle], html: { class: "order_cycle" } do |f| + + = render 'wizard_progress' + + %fieldset.no-border-bottom + %legend{ align: 'center'}= t('.checkout_options') + + %table.checkout-options + %thead + %tr + %th= t('.distributor') + %th= t('.shipping_methods') + %th= t('.payment_methods') + - @order_cycle.distributors.each do |distributor| + - payment_methods = @order_cycle.attachable_payment_methods.where("distributor_id = ?", distributor.id).reject { |payment_method| shared_payment_methods.include?(payment_method) } + - shipping_methods = @order_cycle.attachable_shipping_methods.where("distributor_id = ?", distributor.id).reject { |shipping_method| shared_shipping_methods.include?(shipping_method) } + %tr + %td= distributor.name + %td + - shipping_methods.each do |shipping_method| + %p + %label + = check_box_tag "order_cycle[preferred_shipping_method_ids][]", + shipping_method.id, @order_cycle.shipping_methods.include?(shipping_method), + id: "order_cycle_preferred_shipping_method_ids_#{shipping_method.id}" + = shipping_method.name + - distributor.shipping_methods.backend.each do |shipping_method| + %label.disabled + = check_box_tag nil, nil, false, disabled: true + = shipping_method.name + = "(#{t('.back_end')})" + - if shipping_methods.none? && distributor.shipping_methods.backend.none? + %p.text-center + = t('.no_shipping_methods') + %td + - if payment_methods.any? + %ul + - payment_methods.each do |payment_method| + %li= payment_method.name + - else + %p.text-center + = t('.no_payment_methods') + - if shared_payment_methods.any? || shared_shipping_methods.any? + %tr + %td= t('.shared') + %td + - if shared_shipping_methods.any? + = f.collection_check_boxes :shipping_method_ids, shared_shipping_methods, :id, :name do |input| + - shared_shipping_method = input.object + %p + = input.check_box + = input.label + %p + = "—#{shared_shipping_method.distributors.where(id: @order_cycle.distributor_ids).map(&:name).join(", ")}".html_safe + %td + - if shared_payment_methods.any? + %ul + - shared_payment_methods.each do |shared_payment_method| + %li + = shared_payment_method.name + %p + = "—#{shared_payment_method.distributors.where(id: @order_cycle.distributor_ids).map(&:name).join(", ")}".html_safe + + %div#save-bar + %div.container + %div.seven.columns.alpha + - if @order_cycle.errors.any? + %h5#status-message.error + = @order_cycle.errors.to_a.to_sentence + %div.nine.columns.omega.text-right + = hidden_field_tag :context, :checkout_options + = f.submit t('.save'), class: "red", name: :save + = f.submit t('.save_and_back_to_list'), class: "red", name: :save_and_back_to_list + %a.button.cancel{ href: main_app.admin_order_cycles_path } + = t('.cancel') diff --git a/app/views/admin/order_cycles/outgoing.html.haml b/app/views/admin/order_cycles/outgoing.html.haml index 9924e3dae9..e7756a713d 100644 --- a/app/views/admin/order_cycles/outgoing.html.haml +++ b/app/views/admin/order_cycles/outgoing.html.haml @@ -10,7 +10,8 @@ %save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" } %input.red{ type: "button", value: t('.save'), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } } - %input.red{ type: "button", value: t('.save_and_back_to_list'), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } } + %input.red{ type: "button", value: t('.save_and_next'), ng: { click: "submit($event, '#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } } + %input{ type: "button", value: t('.next'), ng: { click: "cancel('#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", disabled: "order_cycle_form.$dirty" } } %input{ type: "button", ng: { value: "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", click: "cancel('#{main_app.admin_order_cycles_path}')" } } %fieldset.no-border-bottom diff --git a/app/webpacker/css/admin/components/save_bar.scss b/app/webpacker/css/admin/components/save_bar.scss index 70f906119f..b60482de11 100644 --- a/app/webpacker/css/admin/components/save_bar.scss +++ b/app/webpacker/css/admin/components/save_bar.scss @@ -11,6 +11,10 @@ h5 { color: $spree-blue; + + &.error { + color: $red-500; + } } input { diff --git a/app/webpacker/css/admin/openfoodnetwork.scss b/app/webpacker/css/admin/openfoodnetwork.scss index 636b938d6d..aa22632fd0 100644 --- a/app/webpacker/css/admin/openfoodnetwork.scss +++ b/app/webpacker/css/admin/openfoodnetwork.scss @@ -96,6 +96,14 @@ form.order_cycle { .icon-question-sign { font-size: 18px; } + table.checkout-options { + ul { + margin-left: 1em; + } + p, li { + margin: 0.5em 0; + } + } table.exchanges { tr td.active { width: 20px; diff --git a/config/locales/en.yml b/config/locales/en.yml index 7c25622af2..ef52faec39 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1173,15 +1173,29 @@ en: tags: "Tags" delivery_details: "Delivery Details" fees: "Fees" + next: "Next" previous: "Previous" save: "Save" - save_and_back_to_list: "Save and Back to List" + save_and_next: "Save and Next" cancel: "Cancel" back_to_list: "Back To List" + checkout_options: + back_end: "Back office only" + cancel: "Cancel" + checkout_options: "Checkout options" + distributor: "Distributor" + no_payment_methods: Each distributor on this order cycle requires at least one payment method. + no_shipping_methods: Each distributor on this order cycle requires at least one shipping method. + payment_methods: "Payment Methods" + save: "Save" + save_and_back_to_list: "Save and Back to List" + shared: "Shared" + shipping_methods: "Shipping Methods" wizard_progress: edit: "1. General Settings" incoming: "2. Incoming Products" outgoing: "3. Outgoing Products" + checkout_options: "4. Checkout Options" exchange_form: pickup_time_tip: When orders from this OC will be ready for the customer pickup_instructions_placeholder: "Pick-up instructions" diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 7fc4afcd8f..99beb534d0 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -15,6 +15,7 @@ Openfoodnetwork::Application.routes.draw do post :bulk_update, on: :collection, as: :bulk_update get :incoming get :outgoing + get :checkout_options member do get :clone diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index 16d21fdabd..06443fb7ef 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -677,6 +677,24 @@ describe OrderCycle do end end + describe "#attachable_shipping_methods" do + it "includes shipping methods from the distributors on the order cycle" do + shipping_method = create(:shipping_method) + enterprise = create(:enterprise, shipping_methods: [shipping_method]) + oc = create(:simple_order_cycle, distributors: [enterprise]) + + expect(oc.attachable_shipping_methods).to eq([shipping_method]) + end + + it "does not include backoffice only shipping methods" do + shipping_method = create(:shipping_method, display_on: "back_end") + enterprise = create(:enterprise, shipping_methods: [shipping_method]) + oc = create(:simple_order_cycle, distributors: [enterprise]) + + expect(oc.attachable_shipping_methods).to be_empty + end + end + describe "#simple?" do it "returns true if the coordinator sells their own products i.e. shops" do order_cycle = build(:simple_order_cycle, coordinator: build(:enterprise, sells: "own")) diff --git a/spec/services/order_available_shipping_methods_spec.rb b/spec/services/order_available_shipping_methods_spec.rb new file mode 100644 index 0000000000..814853d6eb --- /dev/null +++ b/spec/services/order_available_shipping_methods_spec.rb @@ -0,0 +1,269 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OrderAvailableShippingMethods 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(OrderAvailableShippingMethods.new(order).to_a).to eq [] + end + end + + it "does not return 'back office only' shipping method" do + distributor = create(:distributor_enterprise) + frontend_shipping_method = create(:shipping_method, distributors: [distributor]) + backoffice_only_shipping_method = create(:shipping_method, + distributors: [distributor], display_on: 'back_end') + order_cycle = create(:sells_own_order_cycle) + order = build(:order, distributor: distributor, order_cycle: order_cycle) + + available_shipping_methods = OrderAvailableShippingMethods.new(order).to_a + + expect(available_shipping_methods).to eq [frontend_shipping_method] + end + + context "when no tag rules are in effect" do + context "order cycle selling own produce only i.e. shipping methods cannot be customised" do + it "returns all shipping methods belonging to the enterprise" do + order_cycle = create(:sells_own_order_cycle) + enterprise = order_cycle.coordinator + shipping_method = create(:shipping_method, distributors: [enterprise]) + other_enterprise = create(:enterprise) + other_enterprise_shipping_method = create(:shipping_method, + distributors: [other_enterprise]) + order = build(:order, distributor: enterprise, order_cycle: order_cycle) + + available_shipping_methods = OrderAvailableShippingMethods.new(order).to_a + + expect(order_cycle.shipping_methods).to be_empty + expect(available_shipping_methods).to eq [shipping_method] + end + end + + context "distributor order cycle" do + it "only returns shipping methods which belong to the order distributor + and have been added to the order cycle" do + distributor = create(:distributor_enterprise) + shipping_method_i = create(:shipping_method, distributors: [distributor]) + shipping_method_ii = create(:shipping_method, distributors: [distributor]) + order_cycle = create(:simple_order_cycle, + distributors: [distributor], shipping_methods: [shipping_method_i]) + order = build(:order, distributor: distributor, order_cycle: order_cycle) + + available_shipping_methods = OrderAvailableShippingMethods.new(order).to_a + + expect(available_shipping_methods).to eq order_cycle.shipping_methods + expect(available_shipping_methods).to eq [shipping_method_i] + end + + it "doesn't return shipping methods which have been added to the order cycle + when they don't belong to the order distributor" do + distributor_i = create(:distributor_enterprise) + distributor_ii = create(:distributor_enterprise) + shipping_method_i = create(:shipping_method, distributors: [distributor_i]) + shipping_method_ii = create(:shipping_method, distributors: [distributor_ii]) + order_cycle = create(:simple_order_cycle, + distributors: [distributor_i, distributor_ii], + shipping_methods: [shipping_method_i, shipping_method_ii]) + order = build(:order, distributor: distributor_ii, order_cycle: order_cycle) + + available_shipping_methods = OrderAvailableShippingMethods.new(order).to_a + + expect(available_shipping_methods).not_to eq order_cycle.shipping_methods + expect(available_shipping_methods).to eq [shipping_method_ii] + end + end + end + + context "when FilterShippingMethods tag rules are in effect" do + let(:user) { create(:user) } + let(:distributor) { create(:distributor_enterprise) } + let(:other_distributor) { create(:distributor_enterprise) } + let!(:distributor_shipping_method) { create(:shipping_method, distributors: [distributor]) } + let!(:other_distributor_shipping_method) do + create(:shipping_method, distributors: [other_distributor]) + end + let(:customer) { create(:customer, user: user, enterprise: distributor) } + let!(:tag_rule) { + create(:filter_shipping_methods_tag_rule, + enterprise: distributor, + preferred_customer_tags: "local", + preferred_shipping_method_tags: "local-delivery") + } + let!(:default_tag_rule) { + create(:filter_shipping_methods_tag_rule, + enterprise: distributor, + is_default: true, + preferred_shipping_method_tags: "local-delivery") + } + let!(:tagged_sm) { distributor_shipping_method } + let!(:untagged_sm) { other_distributor_shipping_method } + + before do + tagged_sm.update_attribute(:tag_list, 'local-delivery') + distributor.shipping_methods = [tagged_sm, untagged_sm] + end + + context "with a preferred visiblity of 'visible', default visibility of 'hidden'" do + before { + tag_rule.update_attribute(:preferred_matched_shipping_methods_visibility, 'visible') + } + before { + default_tag_rule.update_attribute(:preferred_matched_shipping_methods_visibility, + 'hidden') + } + + context "order cycle selling own produce only" do + 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_shipping_methods) { OrderAvailableShippingMethods.new(order).to_a } + + it "applies default action (hide)" do + expect(available_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + end + end + + context "when a customer is present" do + let(:available_shipping_methods) { OrderAvailableShippingMethods.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_shipping_methods).to include tagged_sm, untagged_sm + 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_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + end + end + end + end + + context "distributor order cycle" do + context "when the shipping method without the tag rule is attached to the order cycle + and the shipping method with the tag rule is not" do + let(:order_cycle) do + create(:distributor_order_cycle, + distributors: [distributor], shipping_methods: [untagged_sm]) + end + let(:order) { build(:order, distributor: distributor, order_cycle: order_cycle) } + let(:available_shipping_methods) { OrderAvailableShippingMethods.new(order, customer).to_a } + + context "when the customer's tags match" do + before do + customer.update_attribute(:tag_list, 'local') + end + + it "doesn't display the shipping method with the prefered visibility 'visible' tag + even though the customer's tags match + because it hasn't been attached to the order cycle" do + expect(available_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + end + end + end + end + end + + context "with a preferred visiblity of 'hidden', default visibility of 'visible'" do + before { + tag_rule.update_attribute(:preferred_matched_shipping_methods_visibility, 'hidden') + } + before { + default_tag_rule.update_attribute(:preferred_matched_shipping_methods_visibility, + 'visible') + } + + context "order cycle selling own produce only" do + 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_shipping_methods) { OrderAvailableShippingMethods.new(order).to_a } + + it "applies default action (show)" do + expect(available_shipping_methods).to include tagged_sm, untagged_sm + end + end + + context "when a customer is present" do + let(:available_shipping_methods) { OrderAvailableShippingMethods.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_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + 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_shipping_methods).to include tagged_sm, untagged_sm + end + end + end + end + + context "distributor order cycle" do + context "when the shipping method without the tag rule is attached to the order cycle + and the shipping method with the tag rule is not" do + let(:order_cycle) do + create(:distributor_order_cycle, + distributors: [distributor], shipping_methods: [untagged_sm]) + end + let(:order) { build(:order, distributor: distributor, order_cycle: order_cycle) } + + context "when the customer is nil" do + let(:available_shipping_methods) { OrderAvailableShippingMethods.new(order).to_a } + + it "doesn't display the shipping method tagged to be visible by default + because it is not attached to the order cycle" do + expect(available_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + end + end + + context "when a customer is present" do + let(:available_shipping_methods) { OrderAvailableShippingMethods.new(order, customer).to_a } + + context "when the customer's tags don't match" do + before do + customer.update_attribute(:tag_list, 'something') + end + + it "doesn't display the shipping method tagged to be visible by default + because it is not attached to the order cycle" do + expect(available_shipping_methods).to include untagged_sm + expect(available_shipping_methods).to_not include tagged_sm + end + end + end + end + end + end + end +end diff --git a/spec/system/admin/order_cycles/complex_creating_specific_time_spec.rb b/spec/system/admin/order_cycles/complex_creating_specific_time_spec.rb index e16d86796f..19ab92a0bb 100644 --- a/spec/system/admin/order_cycles/complex_creating_specific_time_spec.rb +++ b/spec/system/admin/order_cycles/complex_creating_specific_time_spec.rb @@ -22,6 +22,8 @@ describe ' v2 = create(:variant, product: product) distributor = create(:distributor_enterprise, name: 'My distributor', with_payment_and_shipping: true) + shipping_method_i = distributor.shipping_methods.first + shipping_method_ii = create(:shipping_method, distributors: [distributor]) # Relationships required for interface to work create(:enterprise_relationship, parent: supplier, child: coordinator, @@ -129,6 +131,12 @@ describe ' select 'Distributor fee', from: 'order_cycle_outgoing_exchange_0_enterprise_fees_0_enterprise_fee_id' + click_button 'Save and Next' + + # And I select preferred shipping methods + check "order_cycle_preferred_shipping_method_ids_#{shipping_method_i.id}" + uncheck "order_cycle_preferred_shipping_method_ids_#{shipping_method_ii.id}" + click_button 'Save and Back to List' oc = OrderCycle.last @@ -161,5 +169,8 @@ describe ' expect(exchange.pickup_time).to eq('pickup time') expect(exchange.pickup_instructions).to eq('pickup instructions') expect(exchange.tag_list).to eq(['wholesale']) + + # And the shipping method should be attached + expect(oc.shipping_methods).to eq([shipping_method_i]) end end