@@ -74,7 +74,7 @@ def make_product_free(order_id, product_id)
7474 end
7575
7676 def remove_free_product ( order_id , product_id )
77- raise FreeProductNotExists unless @list . contains_free_products?
77+ return unless @list . contains_free_products?
7878 apply FreeProductRemovedFromOrder . new (
7979 data : {
8080 order_id : order_id ,
@@ -177,11 +177,11 @@ def expire
177177 end
178178
179179 on ProductMadeFreeForOrder do |event |
180- @list . replace ( Product , FreeProduct , event . data . fetch ( :product_id ) )
180+ @list . set_free ( event . data . fetch ( :product_id ) )
181181 end
182182
183183 on FreeProductRemovedFromOrder do |event |
184- @list . replace ( FreeProduct , Product , event . data . fetch ( :product_id ) )
184+ @list . restore_nonfree ( event . data . fetch ( :product_id ) )
185185 end
186186
187187 def calculate_total_sub_discounts ( pricing_catalog )
@@ -227,30 +227,8 @@ def remove_item(product_id)
227227 @items = new_items
228228 end
229229
230- end
231-
232- def replace ( from , to , product_id )
233- @products_quantities [ from . new ( product_id ) ] -= 1
234- @products_quantities [ to . new ( product_id ) ] += 1
235- clear_empty_products
236- end
237-
238- def products
239- @products_quantities . keys
240- end
241-
242- def quantities
243- @products_quantities . values
244- end
245-
246- def items
247- @products_quantities . map do |product , quantity |
248- { product_id : product . id , quantity : quantity }
249- end
250- end
251-
252230 def contains_free_products?
253- @products_quantities . keys . any? { | key | key . free? }
231+ @items . any? { | item | item . price == 0 }
254232 end
255233
256234 def base_sum
@@ -273,55 +251,23 @@ def sub_discounts(pricing_catalog, discounts)
273251 end
274252 end
275253
254+ def set_free ( product_id )
255+ idx = @items . index { |item | item . product_id == product_id && item . price != 0 }
256+ old_item = @items . delete_at ( idx )
257+ @items << old_item . with ( price : 0 )
258+ end
259+
260+ def restore_nonfree ( product_id )
261+ idx = @items . index { |item | item . product_id == product_id && item . price == 0 }
262+ old_item = @items . delete_at ( idx )
263+ @items << old_item . with ( price : old_item . catalog_price )
264+ end
276265
277266 def quantities
278267 sub_amounts_total . map do |product_id , h |
279268 { product_id :, quantity : h [ :quantity ] }
280269 end
281270 end
282271 end
283-
284- class Product
285- attr_reader :id
286-
287- def initialize ( id )
288- @id = id
289- end
290-
291- def free?
292- end
293-
294- def eql? ( other )
295- other . instance_of? ( Product ) && id . eql? ( other . id )
296- end
297-
298- alias == eql?
299-
300- def hash
301- Product . hash ^ id . hash
302- end
303- end
304-
305- class FreeProduct
306- attr_reader :id
307-
308- def initialize ( id )
309- @id = id
310- end
311-
312- def free?
313- true
314- end
315-
316- def eql? ( other )
317- other . instance_of? ( FreeProduct ) && id . eql? ( other . id )
318- end
319-
320- alias == eql?
321-
322- def hash
323- FreeProduct . hash ^ id . hash
324- end
325- end
326272 end
327273end
0 commit comments