Skip to content

Commit

Permalink
Merge pull request #1500 from senid231/create-package-counters-in-ser…
Browse files Browse the repository at this point in the history
…vice

Service Provisioning object creates PackageCounter
  • Loading branch information
dmitry-sinina authored Jul 8, 2024
2 parents b22fe2d + baa8393 commit fd664da
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 1 deletion.
4 changes: 4 additions & 0 deletions app/models/billing/package_counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class Billing::PackageCounter < ApplicationRecord
belongs_to :service, class_name: 'Billing::Service', optional: true

validates :duration, presence: true
validates :duration, allow_nil: true, numericality: { only_integer: true }
validates :exclude, inclusion: { in: [true, false] }

before_save { self.prefix ||= '' }

def display_name
"PC##{id}"
Expand Down
4 changes: 4 additions & 0 deletions app/models/billing/provisioning/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ def initialize(service)
@service = service
end

def after_create
nil
end

# Called before renewing the service
def before_renew
nil
Expand Down
96 changes: 96 additions & 0 deletions app/models/billing/provisioning/free_minutes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# frozen_string_literal: true

module Billing
module Provisioning
# Accepts Service Type variables in format:
# {
# "prefixes": [
# {
# "prefix": "123",
# "duration": 60,
# "exclude": false
# },
# ...
# ]
# }
# Accepts Service variables in format:
# {
# "prefixes": [
# {
# "prefix": "456",
# "duration": 60,
# "exclude": false
# },
# ...
# ],
# "ignore_prefixes": ["123", ...]
# }
# "exclude" is optional and defaults to false
# "ignore_prefixes" is optional and defaults to []
#
class FreeMinutes < Base
def after_create
raise ArgumentError, 'No prefixes configured' if prefixes.empty?

prefixes_data.each do |data|
create_or_reset_counter(data)
end
end

def after_success_renew
raise ArgumentError, 'No prefixes configured' if prefixes.empty?

prefixes_data.each do |data|
create_or_reset_counter(data)
end
destroy_obsolete_counters
end

private

# if counter for prefix does not exist - will created it.
# if counter for prefix exists - will reset duration and exclude.
def create_or_reset_counter(data)
counter = Billing::PackageCounter.find_or_initialize_by(account:, service:, prefix: data['prefix'])
counter.assign_attributes(
duration: data['duration'],
exclude: data['exclude']
)
counter.save!
end

def destroy_obsolete_counters
Billing::PackageCounter.where(service:).where.not(prefix: prefixes).find_each(&:destroy!)
end

def prefixes
prefixes_data.map { |data| data['prefix'] }
end

def prefixes_data
@prefixes_data ||= build_prefixes_data
end

def build_prefixes_data
# service may override some service.type prefixes
ignore_type_prefixes = service.variables['prefixes'].map { |data| data['prefix'] }
# service may ignore some service.type prefixes
ignore_type_prefixes += service.variables['ignore_prefixes'] || []

data_list = []
service.type.variables['prefixes'].each do |data|
next if ignore_type_prefixes.include? data['prefix']

data_list << data
end
service.variables['prefixes'].each do |data|
data_list << data
end
data_list.map do |data|
data['exclude'] = false if data['exclude'].nil?
data
end
end
end
end
end
4 changes: 4 additions & 0 deletions app/models/billing/provisioning/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
module Billing
module Provisioning
class Logging < Base
def after_create
Rails.logger.info "Service created service_id=#{service.id}"
end

def before_renew
Rails.logger.info "Renew started service_id=#{service.id}"
end
Expand Down
10 changes: 10 additions & 0 deletions app/models/billing/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class Billing::Service < ApplicationRecord
belongs_to :type, class_name: 'Billing::ServiceType'
belongs_to :account, class_name: 'Account'
has_many :transactions, class_name: 'Billing::Transaction', dependent: :restrict_with_error
has_many :package_counters, class_name: 'Billing::PackageCounter', dependent: :destroy

attr_readonly :account_id, :type_id

Expand All @@ -63,6 +64,7 @@ class Billing::Service < ApplicationRecord
validate :validate_variables

after_create :create_initial_transaction
after_create :provisioning_object_after_create

scope :ready_for_renew, lambda {
where('renew_period_id is not null AND renew_at <= ? ', Time.current)
Expand Down Expand Up @@ -98,8 +100,16 @@ def variables_json=(value)
self.variables = value
end

def build_provisioning_object
type.provisioning_class.constantize.new(self)
end

private

def provisioning_object_after_create
build_provisioning_object.after_create
end

def validate_variables
errors.add(:variables, 'must be a JSON object or empty') if !variables.nil? && !variables.is_a?(Hash)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/billing/service/renew.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def perform
private

def provisioning_object
@provisioning_object ||= service.type.provisioning_class.constantize.new(service)
@provisioning_object ||= service.build_provisioning_object
end

def next_renew_at
Expand Down

0 comments on commit fd664da

Please sign in to comment.