Skip to content

Commit 5ea98b3

Browse files
authored
Merge pull request #6292 from mamhoff/move-load-promotions-out-of-order-adjuster
Move LoadPromotions out of OrderAdjuster namespace
2 parents 2281dab + 987fd44 commit 5ea98b3

File tree

5 files changed

+149
-122
lines changed

5 files changed

+149
-122
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
module SolidusPromotions
4+
class LoadPromotions
5+
def initialize(order:, dry_run_promotion: nil)
6+
@order = order
7+
@dry_run_promotion = dry_run_promotion
8+
end
9+
10+
def call
11+
promos = connected_order_promotions | sale_promotions
12+
promos << dry_run_promotion if dry_run_promotion
13+
promos.flat_map(&:benefits).group_by(&:preload_relations).each do |benefit_preload_relations, benefits|
14+
preload(records: benefits, associations: benefit_preload_relations)
15+
benefits.flat_map(&:conditions).group_by(&:preload_relations).each do |condition_preload_relations, conditions|
16+
preload(records: conditions, associations: condition_preload_relations)
17+
end
18+
end
19+
promos.reject { |promotion| promotion.usage_limit_exceeded?(excluded_orders: [order]) }
20+
end
21+
22+
private
23+
24+
attr_reader :order, :dry_run_promotion
25+
26+
def preload(records:, associations:)
27+
ActiveRecord::Associations::Preloader.new(records: records, associations: associations).call
28+
end
29+
30+
def connected_order_promotions
31+
eligible_connected_promotion_ids = order.solidus_order_promotions.select do |order_promotion|
32+
order_promotion.promotion.kept? && (order_promotion.promotion_code.nil? || !order_promotion.promotion_code.usage_limit_exceeded?(excluded_orders: [order]))
33+
end.map(&:promotion_id)
34+
order.solidus_promotions.active(reference_time).where(id: eligible_connected_promotion_ids).includes(promotion_includes)
35+
end
36+
37+
def sale_promotions
38+
SolidusPromotions::Promotion.kept.where(apply_automatically: true).active(reference_time).includes(promotion_includes)
39+
end
40+
41+
def reference_time
42+
order.completed_at || Time.current
43+
end
44+
45+
def promotion_includes
46+
{
47+
benefits: :conditions
48+
}
49+
end
50+
end
51+
end

promotions/app/models/solidus_promotions/order_adjuster.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ class OrderAdjuster
77
def initialize(order, dry_run_promotion: nil)
88
@order = order
99
@dry_run = !!dry_run_promotion
10-
@promotions = LoadPromotions.new(order: order, dry_run_promotion: dry_run_promotion).call
10+
@promotions = SolidusPromotions::LoadPromotions.new(
11+
order: order,
12+
dry_run_promotion: dry_run_promotion
13+
).call
1114
end
1215

1316
def call

promotions/app/models/solidus_promotions/order_adjuster/load_promotions.rb

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,10 @@
22

33
module SolidusPromotions
44
class OrderAdjuster
5-
class LoadPromotions
6-
def initialize(order:, dry_run_promotion: nil)
7-
@order = order
8-
@dry_run_promotion = dry_run_promotion
9-
end
10-
11-
def call
12-
promos = connected_order_promotions | sale_promotions
13-
promos << dry_run_promotion if dry_run_promotion
14-
promos.flat_map(&:benefits).group_by(&:preload_relations).each do |benefit_preload_relations, benefits|
15-
preload(records: benefits, associations: benefit_preload_relations)
16-
benefits.flat_map(&:conditions).group_by(&:preload_relations).each do |condition_preload_relations, conditions|
17-
preload(records: conditions, associations: condition_preload_relations)
18-
end
19-
end
20-
promos.reject { |promotion| promotion.usage_limit_exceeded?(excluded_orders: [order]) }
21-
end
22-
23-
private
24-
25-
attr_reader :order, :dry_run_promotion
26-
27-
def preload(records:, associations:)
28-
ActiveRecord::Associations::Preloader.new(records: records, associations: associations).call
29-
end
30-
31-
def connected_order_promotions
32-
eligible_connected_promotion_ids = order.solidus_order_promotions.select do |order_promotion|
33-
order_promotion.promotion.kept? && (order_promotion.promotion_code.nil? || !order_promotion.promotion_code.usage_limit_exceeded?(excluded_orders: [order]))
34-
end.map(&:promotion_id)
35-
order.solidus_promotions.active(reference_time).where(id: eligible_connected_promotion_ids).includes(promotion_includes)
36-
end
37-
38-
def sale_promotions
39-
SolidusPromotions::Promotion.kept.where(apply_automatically: true).active(reference_time).includes(promotion_includes)
40-
end
41-
42-
def reference_time
43-
order.completed_at || Time.current
44-
end
45-
46-
def promotion_includes
47-
{
48-
benefits: :conditions
49-
}
5+
class LoadPromotions < SolidusPromotions::LoadPromotions
6+
def initialize(...)
7+
Spree.deprecator.warn("Please use SolidusPromotions::LoadPromotions instead")
8+
super
509
end
5110
end
5211
end
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# frozen_string_literal: true
2+
3+
require "rails_helper"
4+
5+
RSpec.describe SolidusPromotions::LoadPromotions do
6+
describe "selecting promotions" do
7+
subject { described_class.new(order: order).call }
8+
9+
let(:order) { create(:order) }
10+
11+
let!(:active_promotion) { create(:solidus_promotion, :with_adjustable_benefit, apply_automatically: true) }
12+
let!(:inactive_promotion) do
13+
create(:solidus_promotion, :with_adjustable_benefit, expires_at: 2.days.ago, apply_automatically: true)
14+
end
15+
let!(:connectable_promotion) { create(:solidus_promotion, :with_adjustable_benefit) }
16+
let!(:connectable_inactive_promotion) do
17+
create(:solidus_promotion, :with_adjustable_benefit, expires_at: 2.days.ago)
18+
end
19+
20+
context "no promo is connected to the order" do
21+
it "returns only active promotions" do
22+
expect(subject).to eq([active_promotion])
23+
end
24+
end
25+
26+
context "an active promo is connected to the order" do
27+
before do
28+
order.solidus_promotions << connectable_promotion
29+
end
30+
31+
it "checks active and connected promotions" do
32+
expect(subject).to include(active_promotion, connectable_promotion)
33+
end
34+
end
35+
36+
context "an inactive promo is connected to the order" do
37+
before do
38+
order.solidus_promotions << connectable_inactive_promotion
39+
end
40+
41+
it "does not check connected inactive promotions" do
42+
expect(subject).not_to include(connectable_inactive_promotion)
43+
expect(subject).to eq([active_promotion])
44+
end
45+
end
46+
47+
context "discarded promotions" do
48+
let!(:discarded_promotion) { create(:solidus_promotion, :with_adjustable_benefit, deleted_at: 1.hour.ago, apply_automatically: true) }
49+
50+
it "does not check discarded promotions" do
51+
expect(subject).not_to include(discarded_promotion)
52+
end
53+
54+
context "a discarded promo is connected to the order" do
55+
before do
56+
order.solidus_promotions << discarded_promotion
57+
end
58+
59+
it "does not check connected discarded promotions" do
60+
expect(subject).not_to include(discarded_promotion)
61+
expect(subject).to eq([active_promotion])
62+
end
63+
end
64+
end
65+
end
66+
67+
context "promotions in the past" do
68+
let(:order) { create(:order, completed_at: 7.days.ago) }
69+
let(:currently_active_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 1.hour.ago) }
70+
let(:past_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 1.year.ago, expires_at: 11.months.ago) }
71+
let(:order_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 8.days.ago, expires_at: 6.days.ago) }
72+
73+
before do
74+
order.solidus_promotions << past_promotion
75+
order.solidus_promotions << order_promotion
76+
order.solidus_promotions << currently_active_promotion
77+
end
78+
79+
subject { described_class.new(order: order).call }
80+
81+
it "only evaluates the past promotion that was active when the order was completed" do
82+
expect(subject).to eq([order_promotion])
83+
end
84+
end
85+
end

promotions/spec/models/solidus_promotions/order_adjuster/load_promotions_spec.rb

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,83 +3,12 @@
33
require "rails_helper"
44

55
RSpec.describe SolidusPromotions::OrderAdjuster::LoadPromotions do
6-
describe "selecting promotions" do
7-
subject { described_class.new(order: order).call }
6+
let(:order) { Spree::Order.new }
87

9-
let(:order) { create(:order) }
8+
subject { described_class.new(order:) }
109

11-
let!(:active_promotion) { create(:solidus_promotion, :with_adjustable_benefit, apply_automatically: true) }
12-
let!(:inactive_promotion) do
13-
create(:solidus_promotion, :with_adjustable_benefit, expires_at: 2.days.ago, apply_automatically: true)
14-
end
15-
let!(:connectable_promotion) { create(:solidus_promotion, :with_adjustable_benefit) }
16-
let!(:connectable_inactive_promotion) do
17-
create(:solidus_promotion, :with_adjustable_benefit, expires_at: 2.days.ago)
18-
end
19-
20-
context "no promo is connected to the order" do
21-
it "returns only active promotions" do
22-
expect(subject).to eq([active_promotion])
23-
end
24-
end
25-
26-
context "an active promo is connected to the order" do
27-
before do
28-
order.solidus_promotions << connectable_promotion
29-
end
30-
31-
it "checks active and connected promotions" do
32-
expect(subject).to include(active_promotion, connectable_promotion)
33-
end
34-
end
35-
36-
context "an inactive promo is connected to the order" do
37-
before do
38-
order.solidus_promotions << connectable_inactive_promotion
39-
end
40-
41-
it "does not check connected inactive promotions" do
42-
expect(subject).not_to include(connectable_inactive_promotion)
43-
expect(subject).to eq([active_promotion])
44-
end
45-
end
46-
47-
context "discarded promotions" do
48-
let!(:discarded_promotion) { create(:solidus_promotion, :with_adjustable_benefit, deleted_at: 1.hour.ago, apply_automatically: true) }
49-
50-
it "does not check discarded promotions" do
51-
expect(subject).not_to include(discarded_promotion)
52-
end
53-
54-
context "a discarded promo is connected to the order" do
55-
before do
56-
order.solidus_promotions << discarded_promotion
57-
end
58-
59-
it "does not check connected discarded promotions" do
60-
expect(subject).not_to include(discarded_promotion)
61-
expect(subject).to eq([active_promotion])
62-
end
63-
end
64-
end
65-
end
66-
67-
context "promotions in the past" do
68-
let(:order) { create(:order, completed_at: 7.days.ago) }
69-
let(:currently_active_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 1.hour.ago) }
70-
let(:past_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 1.year.ago, expires_at: 11.months.ago) }
71-
let(:order_promotion) { create(:solidus_promotion, :with_adjustable_benefit, starts_at: 8.days.ago, expires_at: 6.days.ago) }
72-
73-
before do
74-
order.solidus_promotions << past_promotion
75-
order.solidus_promotions << order_promotion
76-
order.solidus_promotions << currently_active_promotion
77-
end
78-
79-
subject { described_class.new(order: order).call }
80-
81-
it "only evaluates the past promotion that was active when the order was completed" do
82-
expect(subject).to eq([order_promotion])
83-
end
10+
it "tells the user to use SolidusPromotions::LoadPromotions instead" do
11+
expect(Spree.deprecator).to receive(:warn).with("Please use SolidusPromotions::LoadPromotions instead")
12+
expect(subject).to be_a(SolidusPromotions::LoadPromotions)
8413
end
8514
end

0 commit comments

Comments
 (0)