summaryrefslogtreecommitdiff
path: root/lib/solidus_subscriptions/subscription_generator.rb
diff options
context:
space:
mode:
authorAlessandro Desantis <desa.alessandro@gmail.com>2021-01-20 10:50:50 +0100
committerAlessandro Desantis <desa.alessandro@gmail.com>2021-01-30 15:23:41 +0100
commitce4edc06e6079d8c098f1d0754e3c8e31b355e2d (patch)
tree064f3682b13e2a67768314802859f6b2b546abfd /lib/solidus_subscriptions/subscription_generator.rb
parent58972478854a4f8f137506591a186a4d528900b9 (diff)
Move all business logic to `lib`
It wasn't clear why certain business logic should live in `app/services` while other should live in `lib`. By unifying everything in one directory, we make it easier for developers to inspect the code and reduce the cognitive load when implementing new classes.
Diffstat (limited to 'lib/solidus_subscriptions/subscription_generator.rb')
-rw-r--r--lib/solidus_subscriptions/subscription_generator.rb65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/solidus_subscriptions/subscription_generator.rb b/lib/solidus_subscriptions/subscription_generator.rb
new file mode 100644
index 0000000..8153912
--- /dev/null
+++ b/lib/solidus_subscriptions/subscription_generator.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+# This module is responsible for taking SolidusSubscriptions::LineItem
+# objects and creating SolidusSubscriptions::Subscription Objects
+module SolidusSubscriptions
+ module SubscriptionGenerator
+ extend self
+
+ SubscriptionConfiguration = Struct.new(:interval_length, :interval_units, :end_date)
+
+ # Create and persist a subscription for a collection of subscription
+ # line items
+ #
+ # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
+ # subscription_line_items to be activated
+ #
+ # @return [SolidusSubscriptions::Subscription]
+ def activate(subscription_line_items)
+ return if subscription_line_items.empty?
+
+ order = subscription_line_items.first.order
+ configuration = subscription_configuration(subscription_line_items.first)
+
+ subscription_attributes = {
+ user: order.user,
+ line_items: subscription_line_items,
+ store: order.store,
+ shipping_address: order.ship_address,
+ billing_address: order.bill_address,
+ payment_source: order.payments.valid.last&.payment_source,
+ payment_method: order.payments.valid.last&.payment_method,
+ **configuration.to_h
+ }
+
+ Subscription.create!(subscription_attributes) do |sub|
+ sub.actionable_date = sub.next_actionable_date
+ end
+ end
+
+ # Group a collection of line items by common subscription configuration
+ # options. Grouped subscription_line_items can belong to a single
+ # subscription.
+ #
+ # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
+ # subscription_line_items to be grouped.
+ #
+ # @return [Array<Array<SolidusSubscriptions::LineItem>>]
+ def group(subscription_line_items)
+ subscription_line_items.group_by do |li|
+ subscription_configuration(li)
+ end.
+ values
+ end
+
+ private
+
+ def subscription_configuration(subscription_line_item)
+ SubscriptionConfiguration.new(
+ subscription_line_item.interval_length,
+ subscription_line_item.interval_units,
+ subscription_line_item.end_date
+ )
+ end
+ end
+end