From 785cdf9bdc9656a0c4fb2f5effd37dd5816276c3 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 28 Jan 2021 00:25:30 +0000 Subject: [PATCH] Extract order fees logic to service --- app/models/spree/order.rb | 22 ++----------- app/services/order_fees_handler.rb | 36 +++++++++++++++++++++ spec/models/spree/order_spec.rb | 16 +++++++-- spec/services/order_fees_handler_spec.rb | 41 ++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 app/services/order_fees_handler.rb create mode 100644 spec/services/order_fees_handler_spec.rb diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index c8acfae5bb..0b4d211c9f 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -669,20 +669,9 @@ module Spree with_lock do EnterpriseFee.clear_all_adjustments_on_order self - fee_calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle) - - loaded_line_items = - line_items.includes(variant: :product).all - - loaded_line_items.each do |line_item| - if provided_by_order_cycle? line_item - fee_calculator.create_line_item_adjustments_for line_item - end - end - - if order_cycle - fee_calculator.create_order_adjustments_for self - end + fee_handler = OrderFeesHandler.new(self) + fee_handler.create_line_item_fees! + fee_handler.create_order_fees! end end @@ -832,11 +821,6 @@ module Spree subscription.present? && order_cycle.orders_close_at.andand > Time.zone.now end - def provided_by_order_cycle?(line_item) - @order_cycle_variant_ids ||= order_cycle&.variants&.map(&:id) || [] - @order_cycle_variant_ids.include? line_item.variant_id - end - def require_customer? return true unless new_record? || state == 'cart' end diff --git a/app/services/order_fees_handler.rb b/app/services/order_fees_handler.rb new file mode 100644 index 0000000000..f3514d4465 --- /dev/null +++ b/app/services/order_fees_handler.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class OrderFeesHandler + attr_reader :order, :distributor, :order_cycle + + def initialize(order) + @order = order + @distributor = order.distributor + @order_cycle = order.order_cycle + end + + def create_line_item_fees! + order.line_items.includes(variant: :product).each do |line_item| + if provided_by_order_cycle? line_item + calculator.create_line_item_adjustments_for line_item + end + end + end + + def create_order_fees! + return unless order_cycle + + calculator.create_order_adjustments_for order + end + + private + + def calculator + @calculator ||= OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle) + end + + def provided_by_order_cycle?(line_item) + @order_cycle_variant_ids ||= order_cycle&.variants&.map(&:id) || [] + @order_cycle_variant_ids.include? line_item.variant_id + end +end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 73f2b228e1..af5d5d6b57 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -533,14 +533,24 @@ describe Spree::Order do end end - describe "updating the distribution charge" do - let(:order) { build(:order) } + describe "applying enterprise fees" do + let(:fee_handler) { ::OrderFeesHandler.new(subject) } + + before do + allow(subject).to receive(:fee_handler) { fee_handler } + end it "clears all enterprise fee adjustments on the order" do expect(EnterpriseFee).to receive(:clear_all_adjustments_on_order).with(subject) subject.update_distribution_charge! end + it "creates line item and order fee adjustments via OrderFeesHandler" do + expect(fee_handler).to receive(:create_line_item_fees!) + expect(fee_handler).to receive(:create_order_fees!) + subject.recreate_all_fees! + end + it "skips order cycle per-order adjustments for orders that don't have an order cycle" do allow(EnterpriseFee).to receive(:clear_all_adjustments_on_order) @@ -552,7 +562,7 @@ describe Spree::Order do it "ensures the correct adjustment(s) are created for order cycles" do allow(EnterpriseFee).to receive(:clear_all_adjustments_on_order) line_item = create(:line_item, order: subject) - allow(subject).to receive(:provided_by_order_cycle?) { true } + allow(fee_handler).to receive(:provided_by_order_cycle?) { true } order_cycle = double(:order_cycle) expect_any_instance_of(OpenFoodNetwork::EnterpriseFeeCalculator). diff --git a/spec/services/order_fees_handler_spec.rb b/spec/services/order_fees_handler_spec.rb new file mode 100644 index 0000000000..e77f0bcc29 --- /dev/null +++ b/spec/services/order_fees_handler_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OrderFeesHandler do + let(:order_cycle) { create(:order_cycle) } + let(:order) { create(:order_with_line_items, line_items_count: 1, order_cycle: order_cycle) } + let(:line_item) { order.line_items.first } + + let(:service) { OrderFeesHandler.new(order) } + let(:calculator) { + double(OpenFoodNetwork::EnterpriseFeeCalculator, create_order_adjustments_for: true) + } + + before do + allow(service).to receive(:calculator) { calculator } + end + + describe "#create_line_item_fees!" do + it "creates per-line-item fee adjustments for line items in the order cycle" do + allow(service).to receive(:provided_by_order_cycle?) { true } + expect(calculator).to receive(:create_line_item_adjustments_for).with(line_item) + + service.create_line_item_fees! + end + end + + describe "#create_order_fees!" do + it "creates per-order adjustment for the order cycle" do + expect(calculator).to receive(:create_order_adjustments_for).with(order) + service.create_order_fees! + end + + it "skips per-order fee adjustments for orders that don't have an order cycle" do + allow(service).to receive(:order_cycle) { nil } + expect(calculator).to_not receive(:create_order_adjustments_for) + + service.create_order_fees! + end + end +end