Skip to content

Commit c088a40

Browse files
Coupons are now per store
Enabled the Coupons read model for mutant.
1 parent 1d2a16e commit c088a40

File tree

16 files changed

+295
-10
lines changed

16 files changed

+295
-10
lines changed

ecommerce/stores/lib/stores.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require_relative "stores/customer_registration"
99
require_relative "stores/offer_registration"
1010
require_relative "stores/time_promotion_registration"
11+
require_relative "stores/coupon_registration"
1112

1213
module Stores
1314

@@ -19,6 +20,7 @@ def call(event_store, command_bus)
1920
command_bus.register(RegisterCustomer, CustomerRegistration.new(event_store))
2021
command_bus.register(RegisterOffer, OfferRegistration.new(event_store))
2122
command_bus.register(RegisterTimePromotion, TimePromotionRegistration.new(event_store))
23+
command_bus.register(RegisterCoupon, CouponRegistration.new(event_store))
2224
end
2325
end
2426
end

ecommerce/stores/lib/stores/commands.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ class RegisterTimePromotion < Infra::Command
2727
attribute :store_id, Infra::Types::UUID
2828
attribute :time_promotion_id, Infra::Types::UUID
2929
end
30+
31+
class RegisterCoupon < Infra::Command
32+
attribute :store_id, Infra::Types::UUID
33+
attribute :coupon_id, Infra::Types::UUID
34+
end
3035
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Stores
2+
class CouponRegistration
3+
def initialize(event_store)
4+
@event_store = event_store
5+
end
6+
7+
def call(cmd)
8+
@event_store.publish(coupon_registered_event(cmd), stream_name: stream_name(cmd))
9+
end
10+
11+
private
12+
13+
def coupon_registered_event(cmd)
14+
CouponRegistered.new(
15+
data: {
16+
store_id: cmd.store_id,
17+
coupon_id: cmd.coupon_id,
18+
}
19+
)
20+
end
21+
22+
def stream_name(cmd)
23+
"Stores::Store$#{cmd.store_id}"
24+
end
25+
end
26+
end

ecommerce/stores/lib/stores/events.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ class TimePromotionRegistered < Infra::Event
2929
attribute :time_promotion_id, Infra::Types::UUID
3030
end
3131

32+
class CouponRegistered < Infra::Event
33+
attribute :store_id, Infra::Types::UUID
34+
attribute :coupon_id, Infra::Types::UUID
35+
end
36+
3237
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require_relative 'test_helper'
2+
module Stores
3+
class CouponRegistrationTest < Test
4+
cover "Stores*"
5+
6+
def test_coupon_should_get_registered
7+
store_id = SecureRandom.uuid
8+
coupon_id = SecureRandom.uuid
9+
assert register_coupon(store_id, coupon_id)
10+
end
11+
12+
def test_should_publish_event
13+
store_id = SecureRandom.uuid
14+
coupon_id = SecureRandom.uuid
15+
coupon_registered = Stores::CouponRegistered.new(data: { store_id: store_id, coupon_id: coupon_id })
16+
assert_events("Stores::Store$#{store_id}", coupon_registered) do
17+
register_coupon(store_id, coupon_id)
18+
end
19+
end
20+
21+
private
22+
23+
def register_coupon(store_id, coupon_id)
24+
run_command(RegisterCoupon.new(store_id: store_id, coupon_id: coupon_id))
25+
end
26+
end
27+
end

rails_application/.mutant.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ requires:
1515
- ./config/environment
1616
matcher:
1717
subjects:
18+
- Coupons*
1819
- Orders*
1920
- ClientOrders*
2021
- Processes*
2122
ignore:
23+
- Coupons::Configuration#call
2224
- Orders::Configuration#call
2325
- Orders::Broadcaster*
2426
- Orders::AddItemToOrder#broadcast_to_ui

rails_application/app/controllers/client/orders_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def remove_item
6262
end
6363

6464
def use_coupon
65-
coupon = Coupons::Coupon.find_by!("lower(code) = ?", params[:coupon_code].downcase)
65+
coupon = Coupons.find_by_code_for_store(params[:coupon_code], current_store_id)
6666
ActiveRecord::Base.transaction do
6767
command_bus.(use_coupon_cmd(params[:id], coupon.uid, coupon.discount))
6868
end
Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
class CouponsController < ApplicationController
22
def index
3-
@coupons = Coupons::Coupon.all
3+
@coupons = Coupons.coupons_for_store(current_store_id)
44
end
55

66
def new
77
@coupon_id = SecureRandom.uuid
88
end
99

1010
def create
11-
create_coupon(params[:coupon_id], params[:name], params[:code], params[:discount])
11+
coupon_id = params[:coupon_id]
12+
13+
ActiveRecord::Base.transaction do
14+
create_coupon(coupon_id)
15+
end
1216
rescue Pricing::Coupon::AlreadyRegistered
1317
flash[:notice] = "Coupon is already registered"
1418
render "new"
@@ -18,12 +22,21 @@ def create
1822

1923
private
2024

21-
def create_coupon(coupon_id, name, code, discount)
22-
command_bus.(create_coupon_cmd(coupon_id, name, code, discount))
23-
end
24-
25-
def create_coupon_cmd(coupon_id, name, code, discount)
26-
Pricing::RegisterCoupon.new(coupon_id: coupon_id, name: name, code: code, discount: discount)
25+
def create_coupon(coupon_id)
26+
command_bus.(
27+
Pricing::RegisterCoupon.new(
28+
coupon_id: coupon_id,
29+
name: params[:name],
30+
code: params[:code],
31+
discount: params[:discount]
32+
)
33+
)
34+
command_bus.(
35+
Stores::RegisterCoupon.new(
36+
coupon_id: coupon_id,
37+
store_id: current_store_id
38+
)
39+
)
2740
end
2841

2942
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Coupons
2+
class AssignStoreToCoupon
3+
def call(event)
4+
Coupon.find_by!(uid: event.data.fetch(:coupon_id)).update!(store_id: event.data.fetch(:store_id))
5+
end
6+
end
7+
end

rails_application/app/read_models/coupons/configuration.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@ class Coupon < ApplicationRecord
33
self.table_name = "coupons"
44
end
55

6+
private_constant :Coupon
7+
8+
def self.coupons_for_store(store_id)
9+
Coupon.where(store_id: store_id)
10+
end
11+
12+
def self.find_by_code_for_store(code, store_id)
13+
Coupon.find_by!("lower(code) = ? AND store_id = ?", code.downcase, store_id)
14+
end
15+
616
class Configuration
717
def call(event_store)
818
event_store.subscribe(RegisterCoupon.new, to: [Pricing::CouponRegistered])
19+
event_store.subscribe(AssignStoreToCoupon.new, to: [Stores::CouponRegistered])
920
end
1021
end
1122
end

0 commit comments

Comments
 (0)