Class: PricingPlans::OverageReporter

Inherits:
Object
  • Object
show all
Defined in:
lib/pricing_plans/overage_reporter.rb

Defined Under Namespace

Classes: OverageItem, Report

Class Method Summary collapse

Class Method Details

.report(plan_owner, target_plan) ⇒ Object

Compute overage against a target plan for the given plan_owner. Returns an array of OverageItem for limits that are over the target. kind: :persistent or :per_period



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/pricing_plans/overage_reporter.rb', line 22

def report(plan_owner, target_plan)
  plan = target_plan.is_a?(PricingPlans::Plan) ? target_plan : Registry.plan(target_plan.to_sym)

  plan.limits.map do |limit_key, limit_config|
    next if limit_config[:to] == :unlimited

    usage = LimitChecker.current_usage_for(plan_owner, limit_key, limit_config)
    allowed = limit_config[:to]
    over_by = [usage - allowed.to_i, 0].max
    next if over_by <= 0

    OverageItem.new(
      limit_key: limit_key,
      kind: (limit_config[:per] ? :per_period : :persistent),
      current_usage: usage,
      allowed: allowed,
      overage: over_by,
      grace_active: GraceManager.grace_active?(plan_owner, limit_key),
      grace_ends_at: GraceManager.grace_ends_at(plan_owner, limit_key)
    )
  end.compact
end

.report_with_message(plan_owner, target_plan) ⇒ Object

Returns a Report with items and a human message suitable for downgrade UX.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/pricing_plans/overage_reporter.rb', line 46

def report_with_message(plan_owner, target_plan)
  items = report(plan_owner, target_plan)
  return Report.new(items: [], message: "No overages on target plan") if items.empty?

  parts = items.map do |i|
    "#{i.limit_key}: #{i.current_usage} > #{i.allowed} (reduce by #{i.overage})"
  end
  grace_info = items.select(&:grace_active).map do |i|
    ends = i.grace_ends_at&.utc&.iso8601
    "#{i.limit_key} grace ends at #{ends}"
  end

  msg = if PricingPlans.configuration&.message_builder
    begin
      built = PricingPlans.configuration.message_builder.call(
        context: :overage_report,
        items: items
      )
      built if built
    rescue StandardError
      nil
    end
  end
  msg ||= "Over target plan on: #{parts.join(', ')}. "
  msg += "Grace active — #{grace_info.join(', ')}." unless grace_info.empty?

  Report.new(items: items, message: msg)
end