Skip to content

Commit 80c4e19

Browse files
committed
Refactor discounts
1 parent 0426d64 commit 80c4e19

File tree

11 files changed

+46
-41
lines changed

11 files changed

+46
-41
lines changed

ecommerce/pricing/lib/pricing.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def call(event_store, command_bus)
6464
SetPercentageDiscountHandler.new(event_store)
6565
)
6666
command_bus.register(
67-
ResetPercentageDiscount,
68-
ResetPercentageDiscountHandler.new(event_store)
67+
RemovePercentageDiscount,
68+
RemovePercentageDiscountHandler.new(event_store)
6969
)
7070
command_bus.register(
7171
ChangePercentageDiscount,

ecommerce/pricing/lib/pricing/apply_time_promotion.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def call(event)
99
command_bus.(ResetTimePromotionDiscount.new(order_id: event.data.fetch(:order_id)))
1010
end
1111

12-
rescue NotPossibleToAssignDiscountTwice, NotPossibleToResetWithoutDiscount
12+
rescue NotPossibleToAssignDiscountTwice, NotPossibleToRemoveWithoutDiscount
1313
end
1414

1515
private

ecommerce/pricing/lib/pricing/commands.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class SetPercentageDiscount < Infra::Command
4040
alias aggregate_id order_id
4141
end
4242

43-
class ResetPercentageDiscount < Infra::Command
43+
class RemovePercentageDiscount < Infra::Command
4444
attribute :order_id, Infra::Types::UUID
4545
alias aggregate_id order_id
4646
end

ecommerce/pricing/lib/pricing/discounts.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ def self.build(discount)
1717
end
1818

1919
class PercentageDiscount
20-
attr_reader :value
20+
attr_reader :value, :type
2121

22-
def initialize(value)
22+
def initialize(type = GENERAL_DISCOUNT, value)
2323
raise UnacceptableDiscountRange if value <= 0
2424
raise UnacceptableDiscountRange if value > 100
2525

26+
@type = type
2627
@value = value
2728
end
2829

ecommerce/pricing/lib/pricing/offer.rb

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Offer
55
def initialize(id)
66
@id = id
77
@list = List.new
8-
@discounts = {}
8+
@discounts = []
99
end
1010

1111
def add_item(product_id)
@@ -26,30 +26,30 @@ def remove_item(product_id)
2626
)
2727
end
2828

29-
def apply_discount(type, discount)
30-
raise NotPossibleToAssignDiscountTwice if @discounts.include?(type)
29+
def apply_discount(discount)
30+
raise NotPossibleToAssignDiscountTwice if discount_exists?(discount.type)
3131
apply PercentageDiscountSet.new(
3232
data: {
3333
order_id: @id,
34-
type: type,
34+
type: discount.type,
3535
amount: discount.value
3636
}
3737
)
3838
end
3939

40-
def change_discount(type, discount)
41-
raise NotPossibleToChangeDiscount unless @discounts.include?(type)
40+
def change_discount(discount)
41+
raise NotPossibleToChangeDiscount unless discount_exists?(discount.type)
4242
apply PercentageDiscountChanged.new(
4343
data: {
4444
order_id: @id,
45-
type: type,
45+
type: discount.type,
4646
amount: discount.value
4747
}
4848
)
4949
end
5050

51-
def reset_discount(type)
52-
raise NotPossibleToResetWithoutDiscount unless @discounts.include?(type)
51+
def remove_discount(type)
52+
raise NotPossibleToRemoveWithoutDiscount unless discount_exists?(type)
5353
apply PercentageDiscountReset.new(
5454
data: {
5555
order_id: @id,
@@ -80,7 +80,7 @@ def remove_free_product(order_id, product_id)
8080

8181
def calculate_total_value(pricing_catalog)
8282
total_value = @list.base_sum(pricing_catalog)
83-
discounted_value = @discounts.values.inject(Discounts::NoPercentageDiscount.new, :add).apply(total_value)
83+
discounted_value = @discounts.inject(Discounts::NoPercentageDiscount.new, :add).apply(total_value)
8484

8585
apply(
8686
OrderTotalValueCalculated.new(
@@ -141,15 +141,16 @@ def use_coupon(coupon_id, discount)
141141
end
142142

143143
on PercentageDiscountSet do |event|
144-
@discounts[event.data.fetch(:type)] = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
144+
@discounts << Discounts::PercentageDiscount.new(event.data.fetch(:type), event.data.fetch(:amount))
145145
end
146146

147147
on PercentageDiscountChanged do |event|
148-
@discounts[event.data.fetch(:type)] = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
148+
@discounts.delete_if { |discount| discount.type == event.data.fetch(:type) }
149+
@discounts << Discounts::PercentageDiscount.new(event.data.fetch(:type), event.data.fetch(:amount))
149150
end
150151

151152
on PercentageDiscountReset do |event|
152-
@discounts.delete(event.data.fetch(:type))
153+
@discounts.delete_if { |discount| discount.type == event.data.fetch(:type) }
153154
end
154155

155156
on ProductMadeFreeForOrder do |event|
@@ -167,6 +168,10 @@ def calculate_total_sub_discounts(pricing_catalog)
167168
on CouponUsed do |event|
168169
end
169170

171+
def discount_exists?(type)
172+
@discounts.find { |discount| discount.type == type }
173+
end
174+
170175
class List
171176

172177
def initialize
@@ -215,7 +220,7 @@ def sub_amounts_total(pricing_catalog)
215220
def sub_discounts(pricing_catalog, discounts)
216221
@products_quantities.map do |product, quantity|
217222
catalog_price_for_single = pricing_catalog.price_for(product)
218-
with_total_discount_single = discounts.values.inject(Discounts::NoPercentageDiscount.new, :add).apply(catalog_price_for_single)
223+
with_total_discount_single = discounts.inject(Discounts::NoPercentageDiscount.new, :add).apply(catalog_price_for_single)
219224
quantity * (catalog_price_for_single - with_total_discount_single)
220225
end
221226
end

ecommerce/pricing/lib/pricing/services.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Pricing
22
class NotPossibleToAssignDiscountTwice < StandardError
33
end
44

5-
class NotPossibleToResetWithoutDiscount < StandardError
5+
class NotPossibleToRemoveWithoutDiscount < StandardError
66
end
77

88
class NotPossibleToChangeDiscount < StandardError
@@ -21,19 +21,19 @@ def initialize(event_store)
2121

2222
def call(cmd)
2323
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
24-
order.apply_discount(Discounts::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
24+
order.apply_discount(Discounts::PercentageDiscount.new(cmd.amount))
2525
end
2626
end
2727
end
2828

29-
class ResetPercentageDiscountHandler
29+
class RemovePercentageDiscountHandler
3030
def initialize(event_store)
3131
@repository = Infra::AggregateRootRepository.new(event_store)
3232
end
3333

3434
def call(cmd)
3535
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
36-
order.reset_discount(Discounts::GENERAL_DISCOUNT)
36+
order.remove_discount(Discounts::GENERAL_DISCOUNT)
3737
end
3838
end
3939
end
@@ -45,7 +45,7 @@ def initialize(event_store)
4545

4646
def call(cmd)
4747
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
48-
order.change_discount(Discounts::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
48+
order.change_discount(Discounts::PercentageDiscount.new(cmd.amount))
4949
end
5050
end
5151
end
@@ -57,7 +57,7 @@ def initialize(event_store)
5757

5858
def call(cmd)
5959
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
60-
order.apply_discount(Discounts::TIME_PROMOTION_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
60+
order.apply_discount(Discounts::PercentageDiscount.new(Discounts::TIME_PROMOTION_DISCOUNT, cmd.amount))
6161
end
6262
end
6363
end
@@ -69,7 +69,7 @@ def initialize(event_store)
6969

7070
def call(cmd)
7171
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
72-
order.reset_discount(Discounts::TIME_PROMOTION_DISCOUNT)
72+
order.remove_discount(Discounts::TIME_PROMOTION_DISCOUNT)
7373
end
7474
end
7575
end

ecommerce/pricing/test/pricing_test.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def test_resets_time_promotion_discount
137137
def test_does_not_reset_time_promotion_discount_if_there_is_none
138138
order_id = SecureRandom.uuid
139139

140-
assert_raises(NotPossibleToResetWithoutDiscount) { reset_time_promotion_discount(order_id) }
140+
assert_raises(NotPossibleToRemoveWithoutDiscount) { reset_time_promotion_discount(order_id) }
141141
end
142142

143143
def test_calculates_total_value_with_discount
@@ -215,7 +215,7 @@ def test_calculates_total_value_with_discount
215215
)
216216
) do
217217
run_command(
218-
Pricing::ResetPercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
218+
Pricing::RemovePercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
219219
)
220220
end
221221
end
@@ -305,7 +305,7 @@ def test_changing_discount_not_possible_when_discount_is_reset
305305
Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10)
306306
)
307307
run_command(
308-
Pricing::ResetPercentageDiscount.new(order_id: order_id)
308+
Pricing::RemovePercentageDiscount.new(order_id: order_id)
309309
)
310310

311311
assert_raises NotPossibleToChangeDiscount do
@@ -414,7 +414,7 @@ def test_resetting_discount_possible_when_discount_has_been_set_and_then_changed
414414
)
415415
) do
416416
run_command(
417-
Pricing::ResetPercentageDiscount.new(order_id: order_id, type: Discounts::GENERAL_DISCOUNT)
417+
Pricing::RemovePercentageDiscount.new(order_id: order_id, type: Discounts::GENERAL_DISCOUNT)
418418
)
419419
end
420420
end
@@ -424,20 +424,20 @@ def test_resetting_with_missing_discount_not_possible
424424
set_price(product_1_id, 20)
425425
order_id = SecureRandom.uuid
426426
add_item(order_id, product_1_id)
427-
assert_raises NotPossibleToResetWithoutDiscount do
427+
assert_raises NotPossibleToRemoveWithoutDiscount do
428428
run_command(
429-
Pricing::ResetPercentageDiscount.new(order_id: order_id)
429+
Pricing::RemovePercentageDiscount.new(order_id: order_id)
430430
)
431431
end
432432
run_command(
433433
Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10)
434434
)
435435
run_command(
436-
Pricing::ResetPercentageDiscount.new(order_id: order_id)
436+
Pricing::RemovePercentageDiscount.new(order_id: order_id)
437437
)
438-
assert_raises NotPossibleToResetWithoutDiscount do
438+
assert_raises NotPossibleToRemoveWithoutDiscount do
439439
run_command(
440-
Pricing::ResetPercentageDiscount.new(order_id: order_id)
440+
Pricing::RemovePercentageDiscount.new(order_id: order_id)
441441
)
442442
end
443443
end

rails_application/app/controllers/orders_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def update_discount
5151

5252
def reset_discount
5353
@order_id = params[:id]
54-
command_bus.(Pricing::ResetPercentageDiscount.new(order_id: @order_id))
54+
command_bus.(Pricing::RemovePercentageDiscount.new(order_id: @order_id))
5555

5656
redirect_to edit_order_path(@order_id)
5757
end

rails_application/test/client_orders/discount_test.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_reset_discount
5757
private
5858

5959
def reset_percentage_discount(order_id)
60-
run_command(Pricing::ResetPercentageDiscount.new(order_id: order_id))
60+
run_command(Pricing::RemovePercentageDiscount.new(order_id: order_id))
6161
end
6262

6363
def set_percentage_discount(order_id)
@@ -96,4 +96,3 @@ def event_store
9696
end
9797
end
9898
end
99-

rails_application/test/orders/discount_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_newest_event_is_always_applied
109109
private
110110

111111
def reset_percentage_discount(order_id)
112-
run_command(Pricing::ResetPercentageDiscount.new(order_id: order_id))
112+
run_command(Pricing::RemovePercentageDiscount.new(order_id: order_id))
113113
end
114114

115115
def set_percentage_discount(order_id)

0 commit comments

Comments
 (0)