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?