Class: Pay::Subscription
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- Pay::Subscription
- Defined in:
- app/models/pay/subscription.rb
Constant Summary collapse
- STATUSES =
%w[incomplete incomplete_expired trialing active past_due canceled unpaid paused]
Class Method Summary collapse
Instance Method Summary collapse
- #active? ⇒ Boolean
- #canceled? ⇒ Boolean
- #cancelled? ⇒ Boolean
- #change_quantity(quantity, **options) ⇒ Object
- #generic_trial? ⇒ Boolean
- #has_incomplete_payment? ⇒ Boolean
- #has_trial? ⇒ Boolean
- #incomplete? ⇒ Boolean
- #latest_payment ⇒ Object
- #no_prorate ⇒ Object
- #on_grace_period? ⇒ Boolean
- #on_trial? ⇒ Boolean
- #past_due? ⇒ Boolean
- #pause_active? ⇒ Boolean
- #payment_processor ⇒ Object
- #processor_subscription(**options) ⇒ Object
- #resume ⇒ Object
- #skip_trial ⇒ Object
- #swap(plan, **options) ⇒ Object
- #swap_and_invoice(plan) ⇒ Object
- #sync!(**options) ⇒ Object
- #trial_ended? ⇒ Boolean
- #will_pause? ⇒ Boolean
Class Method Details
.find_by_processor_and_id(processor, processor_id) ⇒ Object
52 53 54 |
# File 'app/models/pay/subscription.rb', line 52 def self.find_by_processor_and_id(processor, processor_id) joins(:customer).find_by(processor_id: processor_id, pay_customers: {processor: processor}) end |
.pay_processor_for(name) ⇒ Object
56 57 58 |
# File 'app/models/pay/subscription.rb', line 56 def self.pay_processor_for(name) "Pay::#{name.to_s.classify}::Subscription".constantize end |
Instance Method Details
#active? ⇒ Boolean
114 115 116 |
# File 'app/models/pay/subscription.rb', line 114 def active? ["trialing", "active"].include?(status) && (!(canceled? || paused?) || on_trial? || on_grace_period?) end |
#canceled? ⇒ Boolean
93 94 95 |
# File 'app/models/pay/subscription.rb', line 93 def canceled? ends_at? end |
#cancelled? ⇒ Boolean
97 98 99 |
# File 'app/models/pay/subscription.rb', line 97 def cancelled? canceled? end |
#change_quantity(quantity, **options) ⇒ Object
130 131 132 133 |
# File 'app/models/pay/subscription.rb', line 130 def change_quantity(quantity, **) payment_processor.change_quantity(quantity, **) update(quantity: quantity) end |
#generic_trial? ⇒ Boolean
77 78 79 |
# File 'app/models/pay/subscription.rb', line 77 def generic_trial? fake_processor? && trial_ends_at? end |
#has_incomplete_payment? ⇒ Boolean
126 127 128 |
# File 'app/models/pay/subscription.rb', line 126 def has_incomplete_payment? past_due? || incomplete? end |
#has_trial? ⇒ Boolean
81 82 83 |
# File 'app/models/pay/subscription.rb', line 81 def has_trial? trial_ends_at? end |
#incomplete? ⇒ Boolean
122 123 124 |
# File 'app/models/pay/subscription.rb', line 122 def incomplete? status == "incomplete" end |
#latest_payment ⇒ Object
155 156 157 |
# File 'app/models/pay/subscription.rb', line 155 def latest_payment processor_subscription(expand: ["latest_invoice.payment_intent"]).latest_invoice.payment_intent end |
#no_prorate ⇒ Object
69 70 71 |
# File 'app/models/pay/subscription.rb', line 69 def no_prorate self.prorate = false end |
#on_grace_period? ⇒ Boolean
101 102 103 104 |
# File 'app/models/pay/subscription.rb', line 101 def on_grace_period? (ends_at? && Time.current < ends_at) || ((status == "paused" || pause_behavior == "void") && will_pause?) end |
#on_trial? ⇒ Boolean
85 86 87 |
# File 'app/models/pay/subscription.rb', line 85 def on_trial? trial_ends_at? && trial_ends_at.after?(Time.current) end |
#past_due? ⇒ Boolean
118 119 120 |
# File 'app/models/pay/subscription.rb', line 118 def past_due? status == "past_due" end |
#pause_active? ⇒ Boolean
110 111 112 |
# File 'app/models/pay/subscription.rb', line 110 def pause_active? (status == "paused" || pause_behavior == "void") && (pause_starts_at.nil? || pause_starts_at >= Time.current) end |
#payment_processor ⇒ Object
60 61 62 |
# File 'app/models/pay/subscription.rb', line 60 def payment_processor @payment_processor ||= self.class.pay_processor_for(customer.processor).new(self) end |
#processor_subscription(**options) ⇒ Object
151 152 153 |
# File 'app/models/pay/subscription.rb', line 151 def processor_subscription(**) payment_processor.subscription(**) end |
#resume ⇒ Object
135 136 137 138 139 |
# File 'app/models/pay/subscription.rb', line 135 def resume payment_processor.resume update(ends_at: nil, status: :active) self end |
#skip_trial ⇒ Object
73 74 75 |
# File 'app/models/pay/subscription.rb', line 73 def skip_trial self.trial_ends_at = nil end |
#swap(plan, **options) ⇒ Object
141 142 143 144 |
# File 'app/models/pay/subscription.rb', line 141 def swap(plan, **) raise ArgumentError, "plan must be a string. Got `#{plan.inspect}` instead." unless plan.is_a?(String) payment_processor.swap(plan, **) end |
#swap_and_invoice(plan) ⇒ Object
146 147 148 149 |
# File 'app/models/pay/subscription.rb', line 146 def swap_and_invoice(plan) swap(plan) owner.invoice!(subscription_id: processor_id) end |
#sync!(**options) ⇒ Object
64 65 66 67 |
# File 'app/models/pay/subscription.rb', line 64 def sync!(**) self.class.pay_processor_for(customer.processor).sync(processor_id, **) reload end |
#trial_ended? ⇒ Boolean
89 90 91 |
# File 'app/models/pay/subscription.rb', line 89 def trial_ended? trial_ends_at? && trial_ends_at.before?(Time.current) end |
#will_pause? ⇒ Boolean
106 107 108 |
# File 'app/models/pay/subscription.rb', line 106 def will_pause? pause_starts_at? && Time.current < pause_starts_at end |