app/models/subscription_fu/subscription.rb in subscription_fu-0.2.1 vs app/models/subscription_fu/subscription.rb in subscription_fu-0.3.0
- old
+ new
@@ -1,9 +1,9 @@
class SubscriptionFu::Subscription < ActiveRecord::Base
set_table_name :subscriptions
- AVAILABLE_CANCEL_REASONS = %w( update cancel timeout admin )
+ AVAILABLE_CANCEL_REASONS = %w( update cancel gwcancel timeout admin )
default_scope order("created_at ASC", "id ASC")
belongs_to :subject, :polymorphic => true
belongs_to :prev_subscription, :class_name => "SubscriptionFu::Subscription"
@@ -16,14 +16,27 @@
validates :billing_starts_at, :presence => true
validates :paypal_profile_id, :presence => true, :if => :activated_paid_subscription?
validates :cancel_reason, :presence => true, :inclusion => AVAILABLE_CANCEL_REASONS, :if => :canceled?
scope :activated, where("subscriptions.activated_at IS NOT NULL")
+ scope :not_canceled, activated.where("subscriptions.canceled_at IS NULL")
+ scope :using_paypal, where("subscriptions.paypal_profile_id IS NOT NULL")
scope :current, lambda {|time| activated.where("subscriptions.starts_at <= ? AND (subscriptions.canceled_at IS NULL OR subscriptions.canceled_at > ?)", time, time) }
- # TODO this should probably only take plan?key, prev_sub
- def self.build_for_initializing(plan_key, start_time = Time.now, billing_start_time = start_time, prev_sub = nil)
+ def self.sync_all_from_gateway
+ SubscriptionFu::Subscription.using_paypal.not_canceled.each do |s|
+ s.sync_from_gateway!
+ end
+ end
+
+ def self.build_for_initializing(plan_key, prev_sub = nil)
+ if prev_sub
+ start_time = prev_sub.successor_start_date(plan_key)
+ billing_start_time = prev_sub.end_date_when_canceled
+ else
+ billing_start_time = start_time = Time.now
+ end
new(:plan_key => plan_key, :starts_at => start_time, :billing_starts_at => billing_start_time, :prev_subscription => prev_sub)
end
def paid_subscription?
! plan.free_plan? && ! sponsored?
@@ -72,34 +85,43 @@
if new_plan > self.plan
# higher plans always start immediately
Time.now
else
# otherwise they start with the next billing cycle
- successor_billing_start_date
+ end_date_when_canceled
end
end
- def successor_billing_start_date
+ def end_date_when_canceled
# in case this plan was already canceled, this date takes
# precedence (there won't be a next billing time anymore).
canceled_at || next_billing_date || estimated_next_billing_date || Time.now
end
# billing API
- def initiate_activation(admin)
+ def initiate_activation(initiator)
gateway = (plan.free_plan? || sponsored?) ? 'nogw' : 'paypal'
- transactions.create_activation(gateway, admin).tap do |t|
+ transactions.create_activation(gateway, initiator).tap do |t|
if prev_subscription
to_cancel = [prev_subscription]
to_cancel.push(*prev_subscription.next_subscriptions.where("subscriptions.id <> ?", self).all)
- to_cancel.each {|s| s.initiate_cancellation(admin, t) }
+ to_cancel.each {|s| s.initiate_cancellation(initiator, t) }
end
end
end
- def initiate_cancellation(admin, activation_transaction)
- transactions.create_cancellation(admin, activation_transaction, self)
+ def initiate_cancellation(initiator, activation_transaction)
+ transactions.create_cancellation(initiator, activation_transaction, self)
+ end
+
+ def sync_from_gateway!
+ if paypal?
+ if paypal_recurring_details[:status] == SubscriptionFu::Paypal::CANCELED_STATE
+ t = initiate_cancellation(SubscriptionFu::SystemInitiator.paypal_sync_initiator, nil)
+ t.complete(:effective => end_date_when_canceled, :reason => :gwcancel)
+ end
+ end
end
private
def paypal?