Class: Subscription
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Subscription
- Defined in:
- app/models/subscription.rb
Instance Attribute Summary collapse
-
#current_password ⇒ Object
Returns the value of attribute current_password.
Instance Method Summary collapse
-
#allowed_plans ⇒ Object
list of plans this subscriber is allowed to choose use the subscription_plan_check callback in subscriber model.
-
#cancel ⇒ Object
cancelling can mean revert to a free plan and credit back their card if it also means destroying or disabling the user account, that happens elsewhere in your app returns same results as change_plan (nil, false, true).
-
#change_plan(new_plan) ⇒ Object
returns nil if no change, false if failed, or true on success.
-
#charge_balance ⇒ Object
————- charge the current balance against the subscribers credit card return amount charged on success, false for failure, nil for nothing happened.
-
#credit_balance ⇒ Object
credit a negative balance to the subscribers credit card returns amount credited on success, false for failure, nil for nothing.
-
#days_remaining ⇒ Object
number of days until next renewal.
-
#due?(days_from_now = 0) ⇒ Boolean
————- true if account is due today or before.
-
#exceeds_plan?(plan = self.plan) ⇒ Boolean
test if subscriber can use a plan, returns true or false.
-
#grace_days_remaining ⇒ Object
number of days until account expires.
-
#latest_transaction ⇒ Object
most recent transaction.
-
#manual_charge_balance ⇒ Object
————- charge the current balance return amount charged on success, nil for nothing happened.
-
#past_due_days ⇒ Object
number of days account is past due (negative of days_remaining).
-
#plan_check(plan = self.plan) ⇒ Object
check if subscriber can use a plan and returns list of attributes exceeded, or blank for ok.
-
#renew ⇒ Object
returns nil if not past due, false for failed, true for success, or amount charged for success when card was charged.
- #setup_active ⇒ Object
- #setup_expired ⇒ Object
- #setup_free ⇒ Object
- #setup_trial ⇒ Object
-
#trial_ends_on ⇒ Object
date trial ends, or nil if not eligable.
Instance Attribute Details
#current_password ⇒ Object
Returns the value of attribute current_password.
14 15 16 |
# File 'app/models/subscription.rb', line 14 def current_password @current_password end |
Instance Method Details
#allowed_plans ⇒ Object
list of plans this subscriber is allowed to choose use the subscription_plan_check callback in subscriber model
154 155 156 |
# File 'app/models/subscription.rb', line 154 def allowed_plans SubscriptionPlan.all.collect {|plan| plan unless exceeds_plan?(plan) }.compact end |
#cancel ⇒ Object
cancelling can mean revert to a free plan and credit back their card if it also means destroying or disabling the user account, that happens elsewhere in your app returns same results as change_plan (nil, false, true)
99 100 101 102 103 |
# File 'app/models/subscription.rb', line 99 def cancel change_plan SubscriptionPlan.default_plan # uncomment if you want to refund unused value to their credit card, otherwise it just says on balance here #credit_balance end |
#change_plan(new_plan) ⇒ Object
returns nil if no change, false if failed, or true on success
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'app/models/subscription.rb', line 120 def change_plan( new_plan ) # not change? return if plan == new_plan # return unused prepaid value on current plan self.balance -= plan.prorated_value( days_remaining ) if SubscriptionConfig.return_unused_balance && active? # or they owe the used (although unpaid) value on current plan [comment out if you want to be more forgiving] self.balance -= plan.rate - plan.prorated_value( past_due_days ) if past_due? # update the plan self.plan = new_plan # update the state and initialize the renewal date if plan.free? self.free elsif (e = trial_ends_on) self.trial self.next_renewal_on = e #reset end date else #active or past due # note, past due grace period resets like active ones due today, ok? self.active self.next_renewal_on = Time.zone.today self.warning_level = nil end # past_due and expired fall through till next renew # save changes so far save end |
#charge_balance ⇒ Object
charge the current balance against the subscribers credit card
return amount charged on success, false for failure, nil for nothing happened
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'app/models/subscription.rb', line 171 def charge_balance #debugger # nothing to charge? (0 or a credit) return if balance_cents <= 0 # no cc on fle return false if profile.no_info? || profile.profile_key.nil? transaction do # makes this atomic #debugger # charge the card tx = SubscriptionTransaction.charge( balance, profile.profile_key ) # save the transaction transactions.push( tx ) # set profile state and reset balance if tx.success self.update_attribute :balance_cents, 0 profile. else profile.error end tx.success && tx.amount end end |
#credit_balance ⇒ Object
credit a negative balance to the subscribers credit card returns amount credited on success, false for failure, nil for nothing
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'app/models/subscription.rb', line 217 def credit_balance #debugger # nothing to credit? return if balance_cents >= 0 # no cc on fle return false if profile.no_info? || profile.profile_key.nil? transaction do # makes this atomic #debugger # credit the card tx = SubscriptionTransaction.credit( -balance_cents, profile.profile_key, :subscription => self ) # save the transaction transactions.push( tx ) # set profile state and reset balance if tx.success self.update_attribute :balance_cents, 0 profile. else profile.error end tx.success && tx.amount end end |
#days_remaining ⇒ Object
number of days until next renewal
266 267 268 |
# File 'app/models/subscription.rb', line 266 def days_remaining (next_renewal_on - Time.zone.today) unless next_renewal_on.nil? end |
#due?(days_from_now = 0) ⇒ Boolean
true if account is due today or before
243 244 245 |
# File 'app/models/subscription.rb', line 243 def due?( days_from_now = 0) days_remaining && (days_remaining <= days_from_now) end |
#exceeds_plan?(plan = self.plan) ⇒ Boolean
test if subscriber can use a plan, returns true or false
159 160 161 |
# File 'app/models/subscription.rb', line 159 def exceeds_plan?( plan = self.plan) !(plan_check(plan).blank?) end |
#grace_days_remaining ⇒ Object
number of days until account expires
276 277 278 |
# File 'app/models/subscription.rb', line 276 def grace_days_remaining (next_renewal_on + SubscriptionConfig.grace_period.days - Time.zone.today) if past_due? end |
#latest_transaction ⇒ Object
most recent transaction
281 282 283 |
# File 'app/models/subscription.rb', line 281 def latest_transaction transactions.first end |
#manual_charge_balance ⇒ Object
charge the current balance return amount charged on success, nil for nothing happened
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'app/models/subscription.rb', line 198 def manual_charge_balance #debugger # nothing to charge? (0 or a credit) return if balance_cents <= 0 transaction do # makes this atomic #debugger # charge the card tx = SubscriptionTransaction.new(:success => true, :message => 'Successfull', :action => 'Manual Charge', :amount_cents => balance_cents) # save the transaction transactions.push( tx ) self.update_attribute :balance_cents, 0 self.active tx.success && tx.amount end end |
#past_due_days ⇒ Object
number of days account is past due (negative of days_remaining)
271 272 273 |
# File 'app/models/subscription.rb', line 271 def past_due_days (Time.zone.today - next_renewal_on) unless next_renewal_on.nil? end |
#plan_check(plan = self.plan) ⇒ Object
check if subscriber can use a plan and returns list of attributes exceeded, or blank for ok
164 165 166 |
# File 'app/models/subscription.rb', line 164 def plan_check( plan = self.plan) subscriber.subscription_plan_check(plan) end |
#renew ⇒ Object
returns nil if not past due, false for failed, true for success, or amount charged for success when card was charged
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'app/models/subscription.rb', line 70 def renew # make sure it's time return nil unless due? transaction do # makes this atomic #debugger # adjust current balance (except for re-tries) self.balance += plan.rate unless past_due? # charge the amount due case charge = charge_balance # transaction failed: past due and return false when false then Rails.logger.debug 'transaction failed: past due and return false' past_due && false # not charged, subtracted from current balance: update renewal and return true when nil then Rails.logger.debug 'not charged, subtracted from current balance: update renewal and return true' active && true # card was charged: update renewal and return amount else Rails.logger.debug 'card was charged: update renewal and return amount' active && charge end end end |
#setup_active ⇒ Object
59 60 61 62 63 |
# File 'app/models/subscription.rb', line 59 def setup_active # next renewal is from when subscription ran out (to change this behavior, set next_renewal to nil before doing renew) start = next_renewal_on || Time.zone.today self.next_renewal_on = start + plan.interval.months end |
#setup_expired ⇒ Object
65 66 67 |
# File 'app/models/subscription.rb', line 65 def setup_expired change_plan SubscriptionPlan.expired_plan end |
#setup_free ⇒ Object
50 51 52 |
# File 'app/models/subscription.rb', line 50 def setup_free self.next_renewal_on = nil end |
#setup_trial ⇒ Object
54 55 56 57 |
# File 'app/models/subscription.rb', line 54 def setup_trial start = Time.zone.today self.next_renewal_on = start + SubscriptionConfig.trial_period.days end |
#trial_ends_on ⇒ Object
date trial ends, or nil if not eligable
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'app/models/subscription.rb', line 248 def trial_ends_on # no trials? return if SubscriptionConfig.trial_period.to_i==0 case # in trial, days remaining when trial? then next_renewal_on # new record? would start from today when plan.nil? then Time.zone.today + SubscriptionConfig.trial_period.days # start or continue a trial? prorate since creation #when active? : else d = created_at.to_date + SubscriptionConfig.trial_period.days d unless d <= Time.zone.today # else nil not eligable end end |