Skip to content

Commit

Permalink
Refactor discounts
Browse files Browse the repository at this point in the history
  • Loading branch information
marlena-b committed Nov 25, 2024
1 parent 0426d64 commit 80c4e19
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 41 deletions.
4 changes: 2 additions & 2 deletions ecommerce/pricing/lib/pricing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def call(event_store, command_bus)
SetPercentageDiscountHandler.new(event_store)
)
command_bus.register(
ResetPercentageDiscount,
ResetPercentageDiscountHandler.new(event_store)
RemovePercentageDiscount,
RemovePercentageDiscountHandler.new(event_store)
)
command_bus.register(
ChangePercentageDiscount,
Expand Down
2 changes: 1 addition & 1 deletion ecommerce/pricing/lib/pricing/apply_time_promotion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def call(event)
command_bus.(ResetTimePromotionDiscount.new(order_id: event.data.fetch(:order_id)))
end

rescue NotPossibleToAssignDiscountTwice, NotPossibleToResetWithoutDiscount
rescue NotPossibleToAssignDiscountTwice, NotPossibleToRemoveWithoutDiscount
end

private
Expand Down
2 changes: 1 addition & 1 deletion ecommerce/pricing/lib/pricing/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SetPercentageDiscount < Infra::Command
alias aggregate_id order_id
end

class ResetPercentageDiscount < Infra::Command
class RemovePercentageDiscount < Infra::Command
attribute :order_id, Infra::Types::UUID
alias aggregate_id order_id
end
Expand Down
5 changes: 3 additions & 2 deletions ecommerce/pricing/lib/pricing/discounts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ def self.build(discount)
end

class PercentageDiscount
attr_reader :value
attr_reader :value, :type

def initialize(value)
def initialize(type = GENERAL_DISCOUNT, value)
raise UnacceptableDiscountRange if value <= 0
raise UnacceptableDiscountRange if value > 100

@type = type
@value = value
end

Expand Down
33 changes: 19 additions & 14 deletions ecommerce/pricing/lib/pricing/offer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Offer
def initialize(id)
@id = id
@list = List.new
@discounts = {}
@discounts = []
end

def add_item(product_id)
Expand All @@ -26,30 +26,30 @@ def remove_item(product_id)
)
end

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

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

def reset_discount(type)
raise NotPossibleToResetWithoutDiscount unless @discounts.include?(type)
def remove_discount(type)
raise NotPossibleToRemoveWithoutDiscount unless discount_exists?(type)
apply PercentageDiscountReset.new(
data: {
order_id: @id,
Expand Down Expand Up @@ -80,7 +80,7 @@ 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 = @discounts.inject(Discounts::NoPercentageDiscount.new, :add).apply(total_value)

apply(
OrderTotalValueCalculated.new(
Expand Down Expand Up @@ -141,15 +141,16 @@ def use_coupon(coupon_id, discount)
end

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

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

on PercentageDiscountReset do |event|
@discounts.delete(event.data.fetch(:type))
@discounts.delete_if { |discount| discount.type == event.data.fetch(:type) }
end

on ProductMadeFreeForOrder do |event|
Expand All @@ -167,6 +168,10 @@ def calculate_total_sub_discounts(pricing_catalog)
on CouponUsed do |event|
end

def discount_exists?(type)
@discounts.find { |discount| discount.type == type }
end

class List

def initialize
Expand Down Expand Up @@ -215,7 +220,7 @@ def sub_amounts_total(pricing_catalog)
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 = discounts.values.inject(Discounts::NoPercentageDiscount.new, :add).apply(catalog_price_for_single)
with_total_discount_single = discounts.inject(Discounts::NoPercentageDiscount.new, :add).apply(catalog_price_for_single)
quantity * (catalog_price_for_single - with_total_discount_single)
end
end
Expand Down
14 changes: 7 additions & 7 deletions ecommerce/pricing/lib/pricing/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Pricing
class NotPossibleToAssignDiscountTwice < StandardError
end

class NotPossibleToResetWithoutDiscount < StandardError
class NotPossibleToRemoveWithoutDiscount < StandardError
end

class NotPossibleToChangeDiscount < StandardError
Expand All @@ -21,19 +21,19 @@ def initialize(event_store)

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.apply_discount(Discounts::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
order.apply_discount(Discounts::PercentageDiscount.new(cmd.amount))
end
end
end

class ResetPercentageDiscountHandler
class RemovePercentageDiscountHandler
def initialize(event_store)
@repository = Infra::AggregateRootRepository.new(event_store)
end

def call(cmd)
@repository.with_aggregate(Offer, cmd.aggregate_id) do |order|
order.reset_discount(Discounts::GENERAL_DISCOUNT)
order.remove_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::GENERAL_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
order.change_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_discount(Discounts::TIME_PROMOTION_DISCOUNT, Discounts::PercentageDiscount.new(cmd.amount))
order.apply_discount(Discounts::PercentageDiscount.new(Discounts::TIME_PROMOTION_DISCOUNT, 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_discount(Discounts::TIME_PROMOTION_DISCOUNT)
order.remove_discount(Discounts::TIME_PROMOTION_DISCOUNT)
end
end
end
Expand Down
18 changes: 9 additions & 9 deletions ecommerce/pricing/test/pricing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def test_resets_time_promotion_discount
def test_does_not_reset_time_promotion_discount_if_there_is_none
order_id = SecureRandom.uuid

assert_raises(NotPossibleToResetWithoutDiscount) { reset_time_promotion_discount(order_id) }
assert_raises(NotPossibleToRemoveWithoutDiscount) { reset_time_promotion_discount(order_id) }
end

def test_calculates_total_value_with_discount
Expand Down Expand Up @@ -215,7 +215,7 @@ def test_calculates_total_value_with_discount
)
) do
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
Pricing::RemovePercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
)
end
end
Expand Down Expand Up @@ -305,7 +305,7 @@ def test_changing_discount_not_possible_when_discount_is_reset
Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10)
)
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id)
Pricing::RemovePercentageDiscount.new(order_id: order_id)
)

assert_raises NotPossibleToChangeDiscount do
Expand Down Expand Up @@ -414,7 +414,7 @@ def test_resetting_discount_possible_when_discount_has_been_set_and_then_changed
)
) do
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id, type: Discounts::GENERAL_DISCOUNT)
Pricing::RemovePercentageDiscount.new(order_id: order_id, type: Discounts::GENERAL_DISCOUNT)
)
end
end
Expand All @@ -424,20 +424,20 @@ def test_resetting_with_missing_discount_not_possible
set_price(product_1_id, 20)
order_id = SecureRandom.uuid
add_item(order_id, product_1_id)
assert_raises NotPossibleToResetWithoutDiscount do
assert_raises NotPossibleToRemoveWithoutDiscount do
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id)
Pricing::RemovePercentageDiscount.new(order_id: order_id)
)
end
run_command(
Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10)
)
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id)
Pricing::RemovePercentageDiscount.new(order_id: order_id)
)
assert_raises NotPossibleToResetWithoutDiscount do
assert_raises NotPossibleToRemoveWithoutDiscount do
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id)
Pricing::RemovePercentageDiscount.new(order_id: order_id)
)
end
end
Expand Down
2 changes: 1 addition & 1 deletion rails_application/app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def update_discount

def reset_discount
@order_id = params[:id]
command_bus.(Pricing::ResetPercentageDiscount.new(order_id: @order_id))
command_bus.(Pricing::RemovePercentageDiscount.new(order_id: @order_id))

redirect_to edit_order_path(@order_id)
end
Expand Down
3 changes: 1 addition & 2 deletions rails_application/test/client_orders/discount_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_reset_discount
private

def reset_percentage_discount(order_id)
run_command(Pricing::ResetPercentageDiscount.new(order_id: order_id))
run_command(Pricing::RemovePercentageDiscount.new(order_id: order_id))
end

def set_percentage_discount(order_id)
Expand Down Expand Up @@ -96,4 +96,3 @@ def event_store
end
end
end

2 changes: 1 addition & 1 deletion rails_application/test/orders/discount_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_newest_event_is_always_applied
private

def reset_percentage_discount(order_id)
run_command(Pricing::ResetPercentageDiscount.new(order_id: order_id))
run_command(Pricing::RemovePercentageDiscount.new(order_id: order_id))
end

def set_percentage_discount(order_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def set_percentage_discount(order_id)

def reset_percentage_discount(order_id)
run_command(
Pricing::ResetPercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
Pricing::RemovePercentageDiscount.new(order_id: order_id, type: Pricing::Discounts::GENERAL_DISCOUNT)
)
end
end
Expand Down

0 comments on commit 80c4e19

Please sign in to comment.