Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
marlena-b committed Nov 17, 2024
1 parent 929f6f4 commit 6ffee12
Show file tree
Hide file tree
Showing 19 changed files with 250 additions and 136 deletions.
8 changes: 2 additions & 6 deletions ecommerce/pricing/lib/pricing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ def call(event_store, command_bus)
PercentageDiscountReset,
PercentageDiscountChanged,
ProductMadeFreeForOrder,
FreeProductRemovedFromOrder,
TimePromotionDiscountSet,
TimePromotionDiscountReset
FreeProductRemovedFromOrder
])
event_store.subscribe(CalculateOrderTotalSubAmountsValue, to: [
PriceItemAdded,
Expand All @@ -126,9 +124,7 @@ def call(event_store, command_bus)
PercentageDiscountReset,
PercentageDiscountChanged,
ProductMadeFreeForOrder,
FreeProductRemovedFromOrder,
TimePromotionDiscountSet,
TimePromotionDiscountReset
FreeProductRemovedFromOrder
])
end
end
Expand Down
2 changes: 2 additions & 0 deletions ecommerce/pricing/lib/pricing/apply_time_promotion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def call(event)
else
command_bus.(ResetTimePromotionDiscount.new(order_id: event.data.fetch(:order_id)))
end

rescue NotPossibleToAssignDiscountTwice, NotPossibleToResetWithoutDiscount
end

private
Expand Down
13 changes: 3 additions & 10 deletions ecommerce/pricing/lib/pricing/discounts.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module Pricing
module Discounts
GENERAL_DISCOUNT = "general_discount"
TIME_PROMOTION_DISCOUNT = "time_promotion_discount"

class UnacceptableDiscountRange < StandardError
end

Expand Down Expand Up @@ -33,10 +36,6 @@ def add(other_discount)
PercentageDiscount.new(new_value)
end

def ==(other)
value == other.value
end

def exists?
true
end
Expand All @@ -58,15 +57,9 @@ def add(other_discount)
end

def value
0
end

def ==(other)
value == other.value
end

def exists?
false
end
end
end
Expand Down
12 changes: 3 additions & 9 deletions ecommerce/pricing/lib/pricing/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,10 @@ class PriceItemValueCalculated < Infra::Event

class PercentageDiscountSet < Infra::Event
attribute :order_id, Infra::Types::UUID
attribute :type, Infra::Types::String
attribute :amount, Infra::Types::PercentageDiscount
end

class TimePromotionDiscountSet < Infra::Event
attribute :order_id, Infra::Types::UUID
attribute :amount, Infra::Types::PercentageDiscount
end

class TimePromotionDiscountReset < Infra::Event
attribute :order_id, Infra::Types::UUID
end

class PriceItemAdded < Infra::Event
attribute :order_id, Infra::Types::UUID
attribute :product_id, Infra::Types::UUID
Expand All @@ -58,10 +50,12 @@ class PriceItemRemoved < Infra::Event

class PercentageDiscountReset < Infra::Event
attribute :order_id, Infra::Types::UUID
attribute :type, Infra::Types::String
end

class PercentageDiscountChanged < Infra::Event
attribute :order_id, Infra::Types::UUID
attribute :type, Infra::Types::String
attribute :amount, Infra::Types::Price
end

Expand Down
65 changes: 20 additions & 45 deletions ecommerce/pricing/lib/pricing/offer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ class Offer
def initialize(id)
@id = id
@list = List.new
@discount = Discounts::NoPercentageDiscount.new
@time_promotion_discount = Discounts::NoPercentageDiscount.new
@discounts = {}
end

def add_item(product_id)
Expand All @@ -27,50 +26,34 @@ def remove_item(product_id)
)
end

def apply_discount(discount)
raise NotPossibleToAssignDiscountTwice if @discount.exists?
def apply_discount(type, discount)
raise NotPossibleToAssignDiscountTwice if @discounts.include?(type)
apply PercentageDiscountSet.new(
data: {
order_id: @id,
type: type,
amount: discount.value
}
)
end

def apply_time_promotion_discount(time_promotion)
return if time_promotion == @time_promotion_discount
apply TimePromotionDiscountSet.new(
data: {
order_id: @id,
amount: time_promotion.value
}
)
end

def reset_time_promotion_discount
return unless @time_promotion_discount.exists?
apply TimePromotionDiscountReset.new(
data: {
order_id: @id
}
)
end

def change_discount(discount)
raise NotPossibleToChangeDiscount unless @discount.exists?
def change_discount(type, discount)
raise NotPossibleToChangeDiscount unless @discounts.include?(type)
apply PercentageDiscountChanged.new(
data: {
order_id: @id,
type: type,
amount: discount.value
}
)
end

def reset_discount
raise NotPossibleToResetWithoutDiscount unless @discount.exists?
def reset_discount(type)
raise NotPossibleToResetWithoutDiscount unless @discounts.include?(type)
apply PercentageDiscountReset.new(
data: {
order_id: @id
order_id: @id,
type: type
}
)
end
Expand All @@ -97,8 +80,8 @@ def remove_free_product(order_id, product_id)

def calculate_total_value(pricing_catalog)
total_value = @list.base_sum(pricing_catalog)
discounted_value = @discounts.values.inject(Discounts::NoPercentageDiscount.new, :add).apply(total_value)

discounted_value = @discount.add(@time_promotion_discount).apply(total_value)
apply(
OrderTotalValueCalculated.new(
data: {
Expand All @@ -112,7 +95,7 @@ def calculate_total_value(pricing_catalog)

def calculate_sub_amounts(pricing_catalog)
sub_amounts_total = @list.sub_amounts_total(pricing_catalog)
sub_discounts = calculate_total_sub_discounts(pricing_catalog, @time_promotion_discount)
sub_discounts = calculate_total_sub_discounts(pricing_catalog)

products = @list.products
quantities = @list.quantities
Expand Down Expand Up @@ -158,23 +141,15 @@ def use_coupon(coupon_id, discount)
end

on PercentageDiscountSet do |event|
@discount = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
@discounts[event.data.fetch(:type)] = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
end

on PercentageDiscountChanged do |event|
@discount = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
end

on TimePromotionDiscountSet do |event|
@time_promotion_discount = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
end

on TimePromotionDiscountReset do |event|
@time_promotion_discount = Discounts::NoPercentageDiscount.new
@discounts[event.data.fetch(:type)] = Discounts::PercentageDiscount.new(event.data.fetch(:amount))
end

on PercentageDiscountReset do |event|
@discount = Discounts::NoPercentageDiscount.new
@discounts.delete(event.data.fetch(:type))
end

on ProductMadeFreeForOrder do |event|
Expand All @@ -185,8 +160,8 @@ def use_coupon(coupon_id, discount)
@list.replace(FreeProduct, Product, event.data.fetch(:product_id))
end

def calculate_total_sub_discounts(pricing_catalog, time_promotions_discount)
@list.sub_discounts(pricing_catalog, time_promotions_discount, @discount)
def calculate_total_sub_discounts(pricing_catalog)
@list.sub_discounts(pricing_catalog, @discounts)
end

on CouponUsed do |event|
Expand Down Expand Up @@ -237,10 +212,10 @@ def sub_amounts_total(pricing_catalog)
@products_quantities.map { |product, quantity| quantity * pricing_catalog.price_for(product) }
end

def sub_discounts(pricing_catalog, time_promotions_discount, discount)
def sub_discounts(pricing_catalog, discounts)
@products_quantities.map do |product, quantity|
catalog_price_for_single = pricing_catalog.price_for(product)
with_total_discount_single = discount.add(time_promotions_discount).apply(catalog_price_for_single)
with_total_discount_single = discounts.values.inject(Discounts::NoPercentageDiscount.new, :add).apply(catalog_price_for_single)
quantity * (catalog_price_for_single - with_total_discount_single)
end
end
Expand Down
10 changes: 5 additions & 5 deletions ecommerce/pricing/lib/pricing/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.apply_discount(Discounts::PercentageDiscount.new(cmd.amount))
order.apply_discount(Discounts::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
end
end
end
Expand All @@ -33,7 +33,7 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.reset_discount
order.reset_discount(Discounts::GENERAL_DISCOUNT)
end
end
end
Expand All @@ -45,7 +45,7 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.change_discount(Discounts::PercentageDiscount.new(cmd.amount))
order.change_discount(Discounts::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
end
end
end
Expand All @@ -57,7 +57,7 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.apply_time_promotion_discount(Discounts::PercentageDiscount.new(cmd.amount))
order.apply_discount(Discounts::TIME_PROMOTION_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
end
end
end
Expand All @@ -69,7 +69,7 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.reset_time_promotion_discount
order.reset_discount(Discounts::TIME_PROMOTION_DISCOUNT)
end
end
end
Expand Down
23 changes: 14 additions & 9 deletions ecommerce/pricing/test/apply_time_promotion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@ def test_applies_biggest_time_promotion_discount
create_active_time_promotion(50)
create_active_time_promotion(30)

assert_events_contain(stream_name(order_id), time_promotion_discount_set_event(order_id, 50)) do
Pricing::ApplyTimePromotion.new.call(item_added_to_basket_event(order_id, product_id))
assert_events_contain(stream_name(order_id), percentage_discount_set_event(order_id, 50)) do
Pricing::ApplyTimePromotion.new.call(item_added_to_basket_event(order_id, product_id))
end
end

def test_resets_time_promotion_discount
order_id = SecureRandom.uuid
product_id = SecureRandom.uuid
create_active_time_promotion(50)
set_time_promotion_discount(order_id, 50)

assert_events_contain(stream_name(order_id), time_promotion_discount_reset_event(order_id)) do
Timecop.travel(1.minute.from_now) do
assert_events_contain(stream_name(order_id), percentage_discount_reset_event(order_id)) do
Pricing::ApplyTimePromotion.new.call(item_added_to_basket_event(order_id, product_id))
end
end
end

Expand Down Expand Up @@ -63,22 +66,24 @@ def item_added_to_basket_event(order_id, product_id)
end

def set_time_promotion_discount(order_id, discount)
run_command(SetTimePromotionDiscount.new(order_id: order_id, amount: 50))
run_command(SetTimePromotionDiscount.new(order_id: order_id, amount: discount))
end

def time_promotion_discount_set_event(order_id, amount)
TimePromotionDiscountSet.new(
def percentage_discount_set_event(order_id, amount)
PercentageDiscountSet.new(
data: {
order_id: order_id,
type: Pricing::Discounts::TIME_PROMOTION_DISCOUNT,
amount: amount
}
)
end

def time_promotion_discount_reset_event(order_id)
TimePromotionDiscountReset.new(
def percentage_discount_reset_event(order_id)
PercentageDiscountReset.new(
data: {
order_id: order_id
order_id: order_id,
type: Pricing::Discounts::TIME_PROMOTION_DISCOUNT
}
)
end
Expand Down
32 changes: 0 additions & 32 deletions ecommerce/pricing/test/discounts_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,6 @@ def test_cannot_add_to_more_than_100

assert_equal(0, combined.apply(100))
end

def test_is_equal_to_another_discount
first_discount = PercentageDiscount.new(50)
second_discount = PercentageDiscount.new(50)

assert_equal(first_discount, second_discount)
end

def test_is_not_equal_to_another_discount
first_discount = PercentageDiscount.new(50)
second_discount = PercentageDiscount.new(60)

refute_equal(first_discount, second_discount)
end
end

class NoPercentageDiscountTest < Test
Expand All @@ -77,24 +63,6 @@ class NoPercentageDiscountTest < Test
def test_doesnt_change_total
assert_equal(100, NoPercentageDiscount.new.apply(100))
end

def test_is_equal_to_another_discount
first_discount = NoPercentageDiscount.new
second_discount = NoPercentageDiscount.new

assert_equal(first_discount, second_discount)
end

def test_is_not_equal_to_another_discount
first_discount = NoPercentageDiscount.new
second_discount = PercentageDiscount.new(50)

refute_equal(first_discount, second_discount)
end

def test_exists_returns_false
assert_equal false, NoPercentageDiscount.new.exists?
end
end
end
end
Loading

0 comments on commit 6ffee12

Please sign in to comment.