diff options
Diffstat (limited to 'lib/solidus_subscriptions')
-rw-r--r-- | lib/solidus_subscriptions/processor.rb | 110 | ||||
-rw-r--r-- | lib/solidus_subscriptions/testing_support/factories/installment_factory.rb | 4 |
2 files changed, 19 insertions, 95 deletions
diff --git a/lib/solidus_subscriptions/processor.rb b/lib/solidus_subscriptions/processor.rb index d56816a..4547cec 100644 --- a/lib/solidus_subscriptions/processor.rb +++ b/lib/solidus_subscriptions/processor.rb @@ -1,116 +1,36 @@ # frozen_string_literal: true -# This class is responsible for finding subscriptions and installments -# which need to be processed. It will group them together by user and attempts -# to process them together. Subscriptions will also be grouped by their -# shiping address id. -# -# This class passes the reponsibility of actually creating the order off onto -# the consolidated installment class. -# -# This class generates `ProcessInstallmentsJob`s module SolidusSubscriptions class Processor class << self - # Find all actionable subscriptions and intallments, group them together - # by user, and schedule a processing job for the group as a batch def run - batched_users_to_be_processed.each { |batch| new(batch).build_jobs } + SolidusSubscriptions::Subscription.actionable.find_each(&method(:process_subscription)) + SolidusSubscriptions::Installment.actionable.with_active_subscription.find_each(&method(:process_installment)) end private - def batched_users_to_be_processed - subscriptions = SolidusSubscriptions::Subscription.arel_table - installments = SolidusSubscriptions::Installment.arel_table + def process_subscription(subscription) + ActiveRecord::Base.transaction do + subscription.successive_skip_count = 0 + subscription.advance_actionable_date - ::Spree.user_class. - joins(:subscriptions). - joins( - subscriptions. - join(installments, Arel::Nodes::OuterJoin). - on(subscriptions[:id].eq(installments[:subscription_id])). - join_sources - ). - where( - SolidusSubscriptions::Subscription.actionable.arel.constraints.reduce(:and). - or(SolidusSubscriptions::Installment.actionable.with_active_subscription.arel.constraints.reduce(:and)) - ). - distinct. - find_in_batches - end - end - - # @return [Array<Spree.user_class>] - attr_reader :users - - # Get a new instance of the SolidusSubscriptions::Processor - # - # @param users [Array<Spree.user_class>] A list of users with actionable - # subscriptions or installments - # - # @return [SolidusSubscriptions::Processor] - def initialize(users) - @users = users - @installments = {} - end - - # Create `ProcessInstallmentsJob`s for the users used to initalize the - # instance - def build_jobs - users.map do |user| - installemts_by_address_and_user = installments(user).group_by do |i| - [i.subscription.shipping_address_id, i.subscription.billing_address_id] - end - - installemts_by_address_and_user.each_value do |grouped_installments| - ProcessInstallmentsJob.perform_later grouped_installments.map(&:id) - end - end - end + subscription.cancel! if subscription.pending_cancellation? + subscription.deactivate! if subscription.can_be_deactivated? - private - - def subscriptions_by_id - @subscriptions_by_id ||= Subscription. - actionable. - includes(:line_items, :user). - where(user_id: user_ids). - group_by(&:user_id) - end - - def retry_installments - @failed_installments ||= Installment. - actionable. - includes(:subscription). - where(solidus_subscriptions_subscriptions: { user_id: user_ids }). - group_by { |i| i.subscription.user_id } - end - - def installments(user) - @installments[user.id] ||= retry_installments.fetch(user.id, []) + new_installments(user) - end - - def new_installments(user) - ActiveRecord::Base.transaction do - subscriptions_by_id.fetch(user.id, []).map do |sub| - sub.successive_skip_count = 0 - sub.advance_actionable_date - sub.cancel! if sub.pending_cancellation? - sub.deactivate! if sub.can_be_deactivated? if SolidusSubscriptions.configuration.clear_past_installments - sub.installments.unfulfilled.each do |installment| - installment.actionable_date = nil - installment.save! + subscription.installments.unfulfilled.actionable.each do |installment| + installment.update!(actionable_date: nil) end end - sub.installments.create! + + subscription.installments.create!(actionable_date: Time.zone.now) end end - end - def user_ids - @user_ids ||= users.map(&:id) + def process_installment(installment) + ProcessInstallmentsJob.perform_later(installment) + end end end end diff --git a/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb b/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb index 2eb5069..20dcc04 100644 --- a/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb +++ b/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb @@ -21,5 +21,9 @@ FactoryBot.define do [association(:installment_detail, :success, installment: @instance, order: order)] end end + + trait :actionable do + actionable_date { Time.zone.now } + end end end |