Extract a OrderCycleClone service

Before it was giving a Rubocop error, probably not a bad idea anyway.
This commit is contained in:
Cillian O'Ruanaidh
2022-10-07 17:43:35 +01:00
parent 4e6d64c0a1
commit 2c14aecf4f
4 changed files with 154 additions and 115 deletions

View File

@@ -168,24 +168,7 @@ class OrderCycle < ApplicationRecord
end
def clone!
oc = dup
oc.name = I18n.t("models.order_cycle.cloned_order_cycle_name", order_cycle: oc.name)
oc.orders_open_at = oc.orders_close_at = oc.mails_sent = oc.processed_at = nil
oc.coordinator_fee_ids = coordinator_fee_ids
# rubocop:disable Layout/LineLength
oc.preferred_product_selection_from_coordinator_inventory_only = preferred_product_selection_from_coordinator_inventory_only
# rubocop:enable Layout/LineLength
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
)
sync_subscriptions
oc.reload
OrderCycleClone.new(self).create
end
def variants

View File

@@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'order_management/subscriptions/proxy_order_syncer'
class OrderCycleClone
def initialize(order_cycle)
@original_order_cycle = order_cycle
end
def create
oc = @original_order_cycle.dup
oc.name = I18n.t("models.order_cycle.cloned_order_cycle_name", order_cycle: oc.name)
oc.orders_open_at = oc.orders_close_at = oc.mails_sent = oc.processed_at = nil
oc.coordinator_fee_ids = @original_order_cycle.coordinator_fee_ids
# rubocop:disable Layout/LineLength
oc.preferred_product_selection_from_coordinator_inventory_only = @original_order_cycle.preferred_product_selection_from_coordinator_inventory_only
# rubocop:enable Layout/LineLength
oc.schedule_ids = @original_order_cycle.schedule_ids
oc.save!
@original_order_cycle.exchanges.each { |e| e.clone!(oc) }
oc.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
oc.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
sync_subscriptions
oc.reload
end
private
def selected_distributor_payment_method_ids
@original_order_cycle.attachable_distributor_payment_methods.map(&:id) &
@original_order_cycle.selected_distributor_payment_method_ids
end
def selected_distributor_shipping_method_ids
@original_order_cycle.attachable_distributor_shipping_methods.map(&:id) &
@original_order_cycle.selected_distributor_shipping_method_ids
end
def sync_subscriptions
return unless @original_order_cycle.schedule_ids.any?
OrderManagement::Subscriptions::ProxyOrderSyncer.new(
Subscription.where(schedule_id: @original_order_cycle.schedule_ids)
).sync!
end
end

View File

@@ -368,93 +368,6 @@ describe OrderCycle do
end
end
describe "clone!" do
it "clones itself" do
coordinator = create(:enterprise);
oc = create(:simple_order_cycle,
coordinator_fees: [create(:enterprise_fee, enterprise: coordinator)],
preferred_product_selection_from_coordinator_inventory_only: true,
automatic_notifications: true, processed_at: Time.zone.now, mails_sent: true)
schedule = create(:schedule, order_cycles: [oc])
ex1 = create(:exchange, order_cycle: oc)
ex2 = create(:exchange, order_cycle: oc)
oc.clone!
occ = OrderCycle.last
expect(occ.name).to eq("COPY OF #{oc.name}")
expect(occ.orders_open_at).to be_nil
expect(occ.orders_close_at).to be_nil
expect(occ.coordinator).not_to be_nil
expect(occ.preferred_product_selection_from_coordinator_inventory_only).to be true
expect(occ.automatic_notifications).to eq(oc.automatic_notifications)
expect(occ.processed_at).to eq(nil)
expect(occ.mails_sent).to eq(nil)
expect(occ.coordinator).to eq(oc.coordinator)
expect(occ.coordinator_fee_ids).not_to be_empty
expect(occ.coordinator_fee_ids).to eq(oc.coordinator_fee_ids)
expect(occ.preferred_product_selection_from_coordinator_inventory_only).to eq(oc.preferred_product_selection_from_coordinator_inventory_only)
expect(occ.schedule_ids).not_to be_empty
expect(occ.schedule_ids).to eq(oc.schedule_ids)
# Check that the exchanges have been cloned.
original_exchange_attributes = oc.exchanges.map { |ex| core_exchange_attributes(ex) }
cloned_exchange_attributes = occ.exchanges.map { |ex| core_exchange_attributes(ex) }
expect(cloned_exchange_attributes).to match_array original_exchange_attributes
end
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)
distributor_shipping_method_i = create(
:shipping_method,
distributors: [distributor]
).distributor_shipping_methods.first
distributor_shipping_method_ii = create(
:shipping_method,
distributors: [distributor],
display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end]
).distributor_shipping_methods.first
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
order_cycle.selected_distributor_shipping_methods = [
distributor_shipping_method_i,
distributor_shipping_method_ii
]
cloned_order_cycle = order_cycle.clone!
expect(cloned_order_cycle.distributor_shipping_methods).to eq [distributor_shipping_method_i]
end
end
end
describe "finding recently closed order cycles" do
it "should give the most recently closed order cycle for a distributor" do
distributor = create(:distributor_enterprise)
@@ -867,14 +780,4 @@ describe OrderCycle do
expect(order_cycle).not_to be_simple
end
end
def core_exchange_attributes(exchange)
exterior_attribute_keys = %w(id order_cycle_id created_at updated_at)
exchange.attributes.
reject { |k| exterior_attribute_keys.include? k }.
merge(
'variant_ids' => exchange.variant_ids.sort,
'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort
)
end
end

View File

@@ -0,0 +1,107 @@
# frozen_string_literal: true
require 'spec_helper'
describe OrderCycleForm do
describe "#create" do
it "clones the order cycle" do
coordinator = create(:enterprise);
oc = create(:simple_order_cycle,
coordinator_fees: [create(:enterprise_fee, enterprise: coordinator)],
preferred_product_selection_from_coordinator_inventory_only: true,
automatic_notifications: true, processed_at: Time.zone.now, mails_sent: true)
schedule = create(:schedule, order_cycles: [oc])
ex1 = create(:exchange, order_cycle: oc)
ex2 = create(:exchange, order_cycle: oc)
occ = OrderCycleClone.new(oc).create
expect(occ.name).to eq("COPY OF #{oc.name}")
expect(occ.orders_open_at).to be_nil
expect(occ.orders_close_at).to be_nil
expect(occ.coordinator).not_to be_nil
expect(occ.preferred_product_selection_from_coordinator_inventory_only).to be true
expect(occ.automatic_notifications).to eq(oc.automatic_notifications)
expect(occ.processed_at).to eq(nil)
expect(occ.mails_sent).to eq(nil)
expect(occ.coordinator).to eq(oc.coordinator)
expect(occ.coordinator_fee_ids).not_to be_empty
expect(occ.coordinator_fee_ids).to eq(oc.coordinator_fee_ids)
expect(occ.preferred_product_selection_from_coordinator_inventory_only).to eq(
oc.preferred_product_selection_from_coordinator_inventory_only
)
expect(occ.schedule_ids).not_to be_empty
expect(occ.schedule_ids).to eq(oc.schedule_ids)
# Check that the exchanges have been cloned.
original_exchange_attributes = oc.exchanges.map { |ex| core_exchange_attributes(ex) }
cloned_exchange_attributes = occ.exchanges.map { |ex| core_exchange_attributes(ex) }
expect(cloned_exchange_attributes).to match_array original_exchange_attributes
end
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)
distributor_shipping_method_i = create(
:shipping_method,
distributors: [distributor]
).distributor_shipping_methods.first
distributor_shipping_method_ii = create(
:shipping_method,
distributors: [distributor],
display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end]
).distributor_shipping_methods.first
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
order_cycle.selected_distributor_shipping_methods = [
distributor_shipping_method_i,
distributor_shipping_method_ii
]
cloned_order_cycle = order_cycle.clone!
expect(cloned_order_cycle.distributor_shipping_methods).to eq [
distributor_shipping_method_i
]
end
end
end
private
def core_exchange_attributes(exchange)
exterior_attribute_keys = %w(id order_cycle_id created_at updated_at)
exchange.attributes.
reject { |k| exterior_attribute_keys.include? k }.
merge(
'variant_ids' => exchange.variant_ids.sort,
'enterprise_fee_ids' => exchange.enterprise_fee_ids.sort
)
end
end