@@ -6,11 +6,11 @@ def initialize(id)
66 @id = id
77 @items = [ ]
88 @discounts = [ ]
9- @accepted = false
9+ @state = :draft
1010 end
1111
1212 def add_item ( product_id , pricing_policy )
13- fail_if_accepted
13+ fail_unless_draft
1414 apply_discounts_to_pricing_policy ( pricing_policy )
1515 items = pricing_policy . apply ( @items , product_id )
1616 apply PriceItemAdded . new (
@@ -24,7 +24,7 @@ def add_item(product_id, pricing_policy)
2424 end
2525
2626 def remove_item ( product_id , catalog_price )
27- fail_if_accepted
27+ fail_unless_draft
2828 item = @items . find { |item | item . product_id == product_id && item . catalog_price == catalog_price }
2929 return unless item
3030 apply PriceItemRemoved . new (
@@ -38,7 +38,7 @@ def remove_item(product_id, catalog_price)
3838 end
3939
4040 def apply_discount ( discount , pricing_policy )
41- fail_if_accepted
41+ fail_unless_draft
4242 raise NotPossibleToAssignDiscountTwice if discount_exists? ( discount . type )
4343 apply PercentageDiscountSet . new (
4444 data : {
@@ -52,7 +52,7 @@ def apply_discount(discount, pricing_policy)
5252 end
5353
5454 def change_discount ( discount , pricing_policy )
55- fail_if_accepted
55+ fail_unless_draft
5656 raise NotPossibleToChangeDiscount unless discount_exists? ( discount . type )
5757 apply PercentageDiscountChanged . new (
5858 data : {
@@ -66,7 +66,7 @@ def change_discount(discount, pricing_policy)
6666 end
6767
6868 def remove_discount ( type , pricing_policy )
69- fail_if_accepted
69+ fail_unless_draft
7070 raise NotPossibleToRemoveWithoutDiscount unless discount_exists? ( type )
7171 apply PercentageDiscountRemoved . new (
7272 data : {
@@ -99,7 +99,7 @@ def remove_free_product(order_id, product_id)
9999 end
100100
101101 def use_coupon ( coupon_id , discount )
102- fail_if_accepted
102+ fail_unless_draft
103103 apply CouponUsed . new (
104104 data : {
105105 order_id : @id ,
@@ -110,6 +110,7 @@ def use_coupon(coupon_id, discount)
110110 end
111111
112112 def accept
113+ raise CantAcceptEmptyOffer if @items . empty?
113114 apply OfferAccepted . new (
114115 data : {
115116 order_id : @id ,
@@ -126,14 +127,20 @@ def accept
126127 end
127128
128129 def reject
129- raise OnlyAcceptedOfferCanBeRejected unless @ accepted
130+ raise OnlyAcceptedOfferCanBeRejected unless accepted?
130131 apply OfferRejected . new ( data : { order_id : @id } )
131132 end
132133
134+ def expire
135+ raise OnlyDraftOfferCanBeExpired unless draft?
136+ apply OfferExpired . new ( data : { order_id : @id } )
137+ end
138+
133139 private
134140
135- def fail_if_accepted
136- raise CantModifyAcceptedOffer if @accepted
141+ def fail_unless_draft
142+ raise CantModifyAcceptedOffer if accepted?
143+ raise CantModifyExpiredOffer if expired?
137144 end
138145
139146 def apply_discounts_to_pricing_policy ( pricing_policy )
@@ -196,17 +203,25 @@ def recalculate_prices(pricing_policy)
196203 end
197204
198205 on OfferAccepted do |_ |
199- @accepted = true
206+ @state = :accepted
200207 end
201208
202209 on OfferRejected do |_ |
203- @accepted = false
210+ @state = :draft
211+ end
212+
213+ on OfferExpired do |_ |
214+ @state = :expired
204215 end
205216
206217 def discount_exists? ( type )
207218 @discounts . find { |discount | discount . type == type }
208219 end
209220
221+ def draft? = @state == :draft
222+ def accepted? = @state == :accepted
223+ def expired? = @state == :expired
224+
210225 ItemPrice = Data . define ( :product_id , :catalog_price , :price )
211226
212227 class List
0 commit comments