Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions ecommerce/pricing/test/apply_time_promotion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ def test_applies_biggest_time_promotion_discount
end
end

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

Timecop.travel(1.minute.from_now) do
assert_events_contain(stream_name(order_id), percentage_discount_reset_event(order_id)) do
assert_events_contain(stream_name(order_id), percentage_discount_removed_event(order_id)) do
Pricing::ApplyTimePromotion.new.call(item_added_to_basket_event(order_id, product_id))
end
end
Expand Down Expand Up @@ -79,7 +79,7 @@ def percentage_discount_set_event(order_id, amount)
)
end

def percentage_discount_reset_event(order_id)
def percentage_discount_removed_event(order_id)
PercentageDiscountRemoved.new(
data: {
order_id: order_id,
Expand Down
8 changes: 4 additions & 4 deletions ecommerce/pricing/test/pricing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_does_not_set_the_same_time_promotion_discount_twice
assert_raises(NotPossibleToAssignDiscountTwice) { set_time_promotion_discount(order_id, 25) }
end

def test_resets_time_promotion_discount
def test_removes_time_promotion_discount
order_id = SecureRandom.uuid
stream = stream_name(order_id)
create_active_time_promotion(25)
Expand Down Expand Up @@ -296,7 +296,7 @@ def test_changing_discount_not_possible_when_discount_is_not_set
end
end

def test_changing_discount_not_possible_when_discount_is_reset
def test_changing_discount_not_possible_when_discount_is_removed
product_1_id = SecureRandom.uuid
set_price(product_1_id, 20)
order_id = SecureRandom.uuid
Expand Down Expand Up @@ -384,7 +384,7 @@ def test_changing_discount_possible_more_than_once
end
end

def test_resetting_discount_possible_when_discount_has_been_set_and_then_changed
def test_removing_discount_possible_when_discount_has_been_set_and_then_changed
product_1_id = SecureRandom.uuid
set_price(product_1_id, 20)
order_id = SecureRandom.uuid
Expand Down Expand Up @@ -419,7 +419,7 @@ def test_resetting_discount_possible_when_discount_has_been_set_and_then_changed
end
end

def test_resetting_with_missing_discount_not_possible
def test_removing_with_missing_discount_not_possible
product_1_id = SecureRandom.uuid
set_price(product_1_id, 20)
order_id = SecureRandom.uuid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def call(event_store)
event_store.subscribe(ProductHandlers::ChangeProductPrice, to: [Pricing::PriceSet])
event_store.subscribe(ProductHandlers::RegisterProduct, to: [ProductCatalog::ProductRegistered])
event_store.subscribe(ProductHandlers::UpdateProductAvailability, to: [Inventory::AvailabilityChanged])
event_store.subscribe(OrderHandlers::UpdateTimePromotionDiscount, to: [Pricing::PercentageDiscountSet])
event_store.subscribe(OrderHandlers::RemoveTimePromotionDiscount, to: [Pricing::PercentageDiscountRemoved])
event_store.subscribe(OrderHandlers::UpdateDiscount, to: [Pricing::PercentageDiscountSet, Pricing::PercentageDiscountChanged])
event_store.subscribe(OrderHandlers::RemoveDiscount, to: [Pricing::PercentageDiscountRemoved])
event_store.subscribe(OrderHandlers::UpdateOrderTotalValue, to: [Pricing::OrderTotalValueCalculated])
Expand Down
24 changes: 24 additions & 0 deletions rails_application/app/read_models/client_orders/order_handlers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,24 @@ def call(event)

class UpdateDiscount
def call(event)
return unless event.data.fetch(:type) == Pricing::Discounts::GENERAL_DISCOUNT

order = Order.find_or_create_by!(order_uid: event.data.fetch(:order_id))
order.percentage_discount = event.data.fetch(:amount)
order.save!
end
end

class UpdateTimePromotionDiscount
def call(event)
return unless event.data.fetch(:type) == Pricing::Discounts::TIME_PROMOTION_DISCOUNT

order = Order.find_or_create_by!(order_uid: event.data.fetch(:order_id))
order.time_promotion_discount = { discount_value: event.data.fetch(:amount).to_f, type: Pricing::Discounts::TIME_PROMOTION_DISCOUNT }
order.save!
end
end

class UpdateOrderTotalValue
def call(event)
order = Order.find_or_create_by!(order_uid: event.data.fetch(:order_id)) { |order| order.state = "Draft" }
Expand Down Expand Up @@ -90,10 +102,22 @@ def call(event)

class RemoveDiscount
def call(event)
return unless event.data.fetch(:type) == Pricing::Discounts::GENERAL_DISCOUNT

order = Order.find_by(order_uid: event.data.fetch(:order_id))
order.percentage_discount = nil
order.save!
end
end

class RemoveTimePromotionDiscount
def call(event)
return unless event.data.fetch(:type) == Pricing::Discounts::TIME_PROMOTION_DISCOUNT

order = Order.find_by(order_uid: event.data.fetch(:order_id))
order.time_promotion_discount = nil
order.save!
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def footer_rows(order)
tfoot class: "border-t-4" do
before_discounts_row(order) if order.discounted_value != order.total_value
general_discount_row(order) if order.percentage_discount
time_promotion_row(order) if order.time_promotion_discount
total_row(order)
end
end
Expand All @@ -95,6 +96,13 @@ def general_discount_row(order)
end
end

def time_promotion_row(order)
tr class: "border-t" do
td(class: "py-2", colspan: 3) { "Time promotion discount" }
td(class: "py-2 text-right") { "#{order.time_promotion_discount["discount_value"]}%" }
end
end

def total_row(order)
tr class: "border-t" do
td(class: "py-2", colspan: 3) { "Total" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddTimePromotionDiscountToClientOrders < ActiveRecord::Migration[7.2]
def change
add_column :client_orders, :time_promotion_discount, :jsonb
end
end
3 changes: 2 additions & 1 deletion rails_application/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2024_10_18_113912) do
ActiveRecord::Schema[7.2].define(version: 2024_11_29_122521) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand Down Expand Up @@ -60,6 +60,7 @@
t.decimal "percentage_discount", precision: 8, scale: 2
t.decimal "total_value", precision: 8, scale: 2
t.decimal "discounted_value", precision: 8, scale: 2
t.jsonb "time_promotion_discount"
end

create_table "clients", force: :cascade do |t|
Expand Down
21 changes: 19 additions & 2 deletions rails_application/test/client_orders/discount_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def test_discount_set
assert_equal 50, order.total_value
assert_equal 45, order.discounted_value
assert_equal 10, order.percentage_discount
assert_nil order.time_promotion_discount
end

def test_discount_changed
Expand All @@ -35,27 +36,43 @@ def test_discount_changed
assert_equal 50, order.total_value
assert_equal 49.5, order.discounted_value
assert_equal 1, order.percentage_discount
assert_nil order.time_promotion_discount
end

def test_remove_discount
def test_does_not_remove_time_promotion_when_removing_percentage_discount
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
customer_registered(customer_id)
prepare_product(product_id)
create_active_time_promotion(50)
item_added_to_basket(order_id, product_id)
set_percentage_discount(order_id)

remove_percentage_discount(order_id)

order = Order.find_by(order_uid: order_id)
assert_equal(50, order.total_value)
assert_equal(50, order.discounted_value)
assert_equal(25, order.discounted_value)
assert_nil(order.percentage_discount)
assert_equal(50, order.time_promotion_discount["discount_value"])
assert_equal("time_promotion_discount", order.time_promotion_discount["type"])
end

private

def create_active_time_promotion(discount)
run_command(
Pricing::CreateTimePromotion.new(
time_promotion_id: SecureRandom.uuid,
discount: discount,
start_time: Time.current - 1,
end_time: Time.current + 1,
label: "Last Minute"
)
)
end

def remove_percentage_discount(order_id)
run_command(Pricing::RemovePercentageDiscount.new(order_id: order_id))
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require "test_helper"

module ClientOrders
class TimePromotionDiscountTest < InMemoryTestCase
cover "ClientOrders*"

def test_time_promotion_set
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
customer_registered(customer_id)
prepare_product(product_id)
create_active_time_promotion(50)
item_added_to_basket(order_id, product_id)

order = ClientOrders::Order.find_by(order_uid: order_id)
assert_equal 50, order.total_value
assert_equal 25, order.discounted_value
assert_equal 50, order.time_promotion_discount["discount_value"]
assert_equal "time_promotion_discount", order.time_promotion_discount["type"]
assert_nil order.percentage_discount
end

def test_does_not_remove_percentage_discount_when_removing_time_promotion
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
customer_registered(customer_id)
prepare_product(product_id)
create_active_time_promotion(50)
set_percentage_discount(order_id)

travel_to Time.current + 1.day do
item_added_to_basket(order_id, product_id)
end

order = ClientOrders::Order.find_by(order_uid: order_id)
assert_equal(50, order.total_value)
assert_equal(45, order.discounted_value)
assert_equal(10, order.percentage_discount)
assert_nil(order.time_promotion_discount)
end

private

def create_active_time_promotion(discount)
run_command(
Pricing::CreateTimePromotion.new(
time_promotion_id: SecureRandom.uuid,
discount: discount,
start_time: Time.current - 1,
end_time: Time.current + 1,
label: "Last Minute"
)
)
end

def set_percentage_discount(order_id)
run_command(Pricing::SetPercentageDiscount.new(order_id: order_id, amount: 10))
end

def item_added_to_basket(order_id, product_id)
run_command(Pricing::AddPriceItem.new(product_id: product_id, order_id: order_id))
end

def prepare_product(product_id)
run_command(
ProductCatalog::RegisterProduct.new(
product_id: product_id,
)
)
run_command(
ProductCatalog::NameProduct.new(
product_id: product_id,
name: "Async Remote"
)
)
run_command(Pricing::SetPrice.new(product_id: product_id, price: 50))
end

def customer_registered(customer_id)
event_store.publish(Crm::CustomerRegistered.new(data: { customer_id: customer_id, name: "Arkency" }))
end

def event_store
Rails.configuration.event_store
end
end
end
1 change: 1 addition & 0 deletions rails_application/test/integration/client_orders_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ def test_current_time_promotion_is_applied
as_client_add_item_to_basket_for_order(product_id, order_id)
as_client_submit_order_for_customer(order_id)

assert_select "tr td", "50.0%"
assert_select "tr td", "$2.00"
end

Expand Down
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 @@ -59,7 +59,7 @@ def test_remove_discount
assert event_store.event_in_stream?(event_store.read.of_type([Pricing::PercentageDiscountRemoved]).last.event_id, "Orders$all")
end

def test_does_not_remove_percentage_discount_when_time_promotion_reset
def test_does_not_remove_percentage_discount_when_removing_time_promotion
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Orders
class RemoveTimePromotionDiscountTest < InMemoryTestCase
cover "Orders*"

def test_resets_time_promotion_discount_value
def test_removes_time_promotion_discount_value
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
Expand All @@ -20,7 +20,7 @@ def test_resets_time_promotion_discount_value
end
end

def test_does_not_reset_time_promotion_when_general_discount_reset
def test_does_not_removes_time_promotion_when_removing_general_discount
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid
Expand Down