From 696ecf2062d320beb085e3b311cfd883c4ea24f3 Mon Sep 17 00:00:00 2001 From: cesartalves Date: Tue, 18 May 2021 13:18:06 -0300 Subject: Subscription Reminders Add a Reminder process / configuration so that subscriptions which are soon to be renewed can be processed (as, for example, to send an email to the customer) --- .../solidus_subscriptions/process_reminder_job.rb | 11 +++++++ .../install/templates/initializer.rb | 7 +++++ lib/solidus_subscriptions.rb | 1 + lib/solidus_subscriptions/configuration.rb | 6 +++- lib/solidus_subscriptions/reminder.rb | 21 +++++++++++++ .../subscription_reminder_policy.rb | 19 ++++++++++++ lib/tasks/process_subscriptions.rake | 6 ++++ spec/lib/solidus_subscriptions/reminder_spec.rb | 34 ++++++++++++++++++++++ 8 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/jobs/solidus_subscriptions/process_reminder_job.rb create mode 100644 lib/solidus_subscriptions/reminder.rb create mode 100644 lib/solidus_subscriptions/subscription_reminder_policy.rb create mode 100644 spec/lib/solidus_subscriptions/reminder_spec.rb diff --git a/app/jobs/solidus_subscriptions/process_reminder_job.rb b/app/jobs/solidus_subscriptions/process_reminder_job.rb new file mode 100644 index 0000000..320f76d --- /dev/null +++ b/app/jobs/solidus_subscriptions/process_reminder_job.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module SolidusSubscriptions + class ProcessReminderJob < ApplicationJob + queue_as { SolidusSubscriptions.configuration.processing_queue } + + def perform(subscription) + # TODO: fill + end + end +end diff --git a/lib/generators/solidus_subscriptions/install/templates/initializer.rb b/lib/generators/solidus_subscriptions/install/templates/initializer.rb index de1d081..5a87cff 100644 --- a/lib/generators/solidus_subscriptions/install/templates/initializer.rb +++ b/lib/generators/solidus_subscriptions/install/templates/initializer.rb @@ -109,4 +109,11 @@ SolidusSubscriptions.configure do |config| # overriding the `extra_attributes` method on a subclass # # config.order_creator_class = 'SolidusSubscriptions::OrderCreator' + + # =================================== Subscription Reminders ===================================== + # + # To send reminders to Subscription customers N days before the subscription is renewed, change this + # + # config.days_for_subscription_reminder = 3.days + # end diff --git a/lib/solidus_subscriptions.rb b/lib/solidus_subscriptions.rb index 9d6457f..f1387d4 100644 --- a/lib/solidus_subscriptions.rb +++ b/lib/solidus_subscriptions.rb @@ -27,6 +27,7 @@ require 'solidus_subscriptions/dispatcher/out_of_stock_dispatcher' require 'solidus_subscriptions/dispatcher/payment_failed_dispatcher' require 'solidus_subscriptions/dispatcher/success_dispatcher' require 'solidus_subscriptions/order_creator' +require 'solidus_subscriptions/reminder' module SolidusSubscriptions class << self diff --git a/lib/solidus_subscriptions/configuration.rb b/lib/solidus_subscriptions/configuration.rb index 9d6c3d2..ad83478 100644 --- a/lib/solidus_subscriptions/configuration.rb +++ b/lib/solidus_subscriptions/configuration.rb @@ -11,7 +11,7 @@ module SolidusSubscriptions :success_dispatcher_class, :failure_dispatcher_class, :payment_failed_dispatcher_class, :out_of_stock_dispatcher, :maximum_successive_skips, :reprocessing_interval, :minimum_cancellation_notice, :processing_queue, :subscription_line_item_attributes, - :subscription_attributes, :subscribable_class, :order_creator_class + :subscription_attributes, :subscribable_class, :order_creator_class, :days_for_subscription_reminder ) def success_dispatcher_class @@ -42,6 +42,10 @@ module SolidusSubscriptions @reprocessing_interval ||= 1.day end + def days_for_subscription_reminder + @days_for_subscription_reminder ||= 0.days + end + def minimum_cancellation_notice @minimum_cancellation_notice ||= 0.days end diff --git a/lib/solidus_subscriptions/reminder.rb b/lib/solidus_subscriptions/reminder.rb new file mode 100644 index 0000000..82bed0a --- /dev/null +++ b/lib/solidus_subscriptions/reminder.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require_relative 'subscription_reminder_policy' + +module SolidusSubscriptions + class Reminder + class << self + def run + SolidusSubscriptions::Subscription + .where(installments: SolidusSubscriptions::Installment.unfulfilled) + .or(SolidusSubscriptions::Subscription.where.not(state: ["canceled", "inactive"])) + .distinct + .find_each + .select { |subscription| SubscriptionReminderPolicy.new(subscription).send_reminder? } + .map do |subscription| + SolidusSubscriptions::ProcessReminderJob.perform_later(subscription) + end + end + end + end +end \ No newline at end of file diff --git a/lib/solidus_subscriptions/subscription_reminder_policy.rb b/lib/solidus_subscriptions/subscription_reminder_policy.rb new file mode 100644 index 0000000..2124bf8 --- /dev/null +++ b/lib/solidus_subscriptions/subscription_reminder_policy.rb @@ -0,0 +1,19 @@ +module SolidusSubscriptions + class SubscriptionReminderPolicy + def initialize(subscription) + @subscription = subscription + end + + def send_reminder? + days_for_reminder = SolidusSubscriptions.configuration.days_for_subscription_reminder + + return false if days_for_reminder.to_i <= 0 + + @subscription.actionable_date == Time.zone.today + days_for_reminder + end + + private + + attr_reader :subscription + end +end diff --git a/lib/tasks/process_subscriptions.rake b/lib/tasks/process_subscriptions.rake index 1da05ec..a0089b5 100644 --- a/lib/tasks/process_subscriptions.rake +++ b/lib/tasks/process_subscriptions.rake @@ -5,4 +5,10 @@ namespace :solidus_subscriptions do task process: :environment do SolidusSubscriptions::Processor.run end + + desc 'Send reminders for subscriptions soon to be renewed' + task send_reminder: :environment do + SolidusSubscriptions::Reminder.run + end + end diff --git a/spec/lib/solidus_subscriptions/reminder_spec.rb b/spec/lib/solidus_subscriptions/reminder_spec.rb new file mode 100644 index 0000000..d4a20ef --- /dev/null +++ b/spec/lib/solidus_subscriptions/reminder_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +RSpec.describe SolidusSubscriptions::Reminder do + let!(:subscription) { + create(:subscription, :with_line_item, :with_shipping_address, :with_billing_address, :actionable, + actionable_date: Time.zone.today + 3.days) + } + + context 'when subscriptions are going to be renewed within the configured days' do + + before do + SolidusSubscriptions.configuration.days_for_subscription_reminder = 3.days + end + + it 'queues the reminder to be delivered' do + expect { + described_class.run + }.to have_enqueued_job(SolidusSubscriptions::ProcessReminderJob) + end + end + + context 'when the configuration is set to 0' do + + before do + SolidusSubscriptions.configuration.days_for_subscription_reminder = 0.days + end + + it 'doesn\'t the reminder to be delivered' do + expect { + described_class.run + }.not_to have_enqueued_job(SolidusSubscriptions::ProcessReminderJob) + end + end +end -- cgit v1.2.3