Skip to content

Commit 8f7af0d

Browse files
committed
refactor ThreePlusOneFree process
Don't call two commands at once when free product need to be changed. Just remove current free product. A new free product will be established on the next process run, when servicing Pricing::FreeProductRemovedFromOrder
1 parent 40dd60a commit 8f7af0d

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed
Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
module Processes
22
class ThreePlusOneFree
33

4-
class ProcessState < Data.define(:lines, :free_product, :eligible_free_product)
5-
def initialize(lines: [], free_product: nil, eligible_free_product: nil) = super
4+
class ProcessState < Data.define(:lines, :free_product)
5+
def initialize(lines: [], free_product: nil) = super
6+
7+
MIN_ORDER_LINES_QUANTITY = 4
8+
9+
def eligible_free_product
10+
if lines.size >= MIN_ORDER_LINES_QUANTITY
11+
line = lines.first
12+
line.fetch(:product_id)
13+
end
14+
end
615
end
716

817
include Infra::ProcessManager.with_state(ProcessState)
@@ -21,45 +30,41 @@ def apply(event)
2130
case event
2231
when Pricing::PriceItemAdded
2332
lines = (state.lines + [{ product_id:, price: event.data.fetch(:price) }]).sort_by { |line| line.fetch(:price) }
24-
state.with(lines:, eligible_free_product: eligible_free_product(lines))
33+
state.with(lines:)
2534
when Pricing::PriceItemRemoved
26-
lines = state.lines
35+
lines = state.lines.dup
2736
index_of_line_to_remove = lines.index { |line| line.fetch(:product_id) == product_id }
2837
lines.delete_at(index_of_line_to_remove)
29-
state.with(lines:, eligible_free_product: eligible_free_product(lines))
38+
state.with(lines:)
3039
when Pricing::ProductMadeFreeForOrder
31-
state.with(free_product: product_id, eligible_free_product: eligible_free_product(state.lines))
40+
state.with(free_product: product_id)
3241
when Pricing::FreeProductRemovedFromOrder
33-
state.with(free_product: nil, eligible_free_product: nil)
42+
state.with(free_product: nil)
3443
end
3544
end
3645

3746
def act
3847
return if state.free_product == state.eligible_free_product
3948

40-
remove_old_free_product if state.free_product
41-
make_new_product_for_free(state.eligible_free_product) if state.eligible_free_product
49+
case [state.free_product, state.eligible_free_product]
50+
in [nil, new_free_product]
51+
make_new_product_for_free(new_free_product)
52+
in [old_free_product, *]
53+
remove_old_free_product(old_free_product)
54+
else
55+
end
4256
end
4357

44-
def remove_old_free_product
45-
command_bus.call(Pricing::RemoveFreeProductFromOrder.new(order_id: id, product_id: state.free_product))
58+
def remove_old_free_product(product_id)
59+
command_bus.call(Pricing::RemoveFreeProductFromOrder.new(order_id: id, product_id:))
4660
end
4761

4862
def make_new_product_for_free(product_id)
49-
command_bus.call(Pricing::MakeProductFreeForOrder.new(order_id: id, product_id: product_id))
63+
command_bus.call(Pricing::MakeProductFreeForOrder.new(order_id: id, product_id:))
5064
end
5165

5266
def fetch_id(event)
5367
event.data.fetch(:order_id)
5468
end
55-
56-
MIN_ORDER_LINES_QUANTITY = 4
57-
58-
def eligible_free_product(lines)
59-
if lines.size >= MIN_ORDER_LINES_QUANTITY
60-
line = lines.first
61-
line.fetch(:product_id)
62-
end
63-
end
6469
end
6570
end

0 commit comments

Comments
 (0)