@@ 1,9 1,10 @@
# frozen_string_literal: true
+require_relative "expiring_lock"
+
class BillPlanCommand
def self.for(customer)
return ForUnregistered.new(customer) unless customer.registered?
- return ForNotExpired.new(customer) unless customer.expires_at <= Time.now
unless customer.balance > customer.monthly_price
return ForLowBalance.new(customer)
@@ 16,19 17,30 @@ class BillPlanCommand
@customer = customer
end
+ def reload_customer(db)
+ @customer = Command.execution.customer_repo.with(db: db)
+ .find(customer_id).sync
+ end
+
def call
- billed = @customer.bill_plan(note: "Renew account plan") { |db|
- @customer = Command.execution.customer_repo.with(db: db)
- .find(@customer.customer_id).sync
- @customer.balance > @customer.monthly_price &&
- @customer.expires_at <= Time.now
- }
- Command.reply do |reply|
- reply.note_type = billed ? :info : :error
- reply.note_text = "#{@customer.customer_id}#{billed ? '' : ' not'} billed"
+ ExpiringLock.new("jmp_customer_bill_plan-#{customer_id}").with {
+ @customer.bill_plan(note: "Renew account plan") { |db|
+ reload_customer(db).balance > @customer.monthly_price
+ }
+ }.then do |billed|
+ Command.reply do |reply|
+ reply.note_type = billed ? :info : :error
+ reply.note_text = "#{customer_id}#{billed ? '' : ' not'} billed"
+ end
end
end
+protected
+
+ def customer_id
+ @customer.customer_id
+ end
+
class ForLowBalance
def initialize(customer)
@customer = customer
@@ 76,17 88,4 @@ class BillPlanCommand
end
end
end
-
- class ForNotExpired
- def initialize(customer)
- @customer = customer
- end
-
- def call
- Command.reply do |reply|
- reply.note_type = :error
- reply.note_text = "#{@customer.customer_id} is not expired"
- end
- end
- end
end