11module 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
6570end
0 commit comments