solidus_subscriptions 1.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +41 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.github_changelog_generator +2 -0
  6. data/.gitignore +20 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +12 -0
  9. data/.rubocop_todo.yml +86 -0
  10. data/CHANGELOG.md +191 -0
  11. data/Gemfile +33 -0
  12. data/LICENSE +26 -0
  13. data/README.md +221 -0
  14. data/Rakefile +6 -0
  15. data/app/assets/javascripts/spree/backend/solidus_subscriptions.js +1 -0
  16. data/app/assets/javascripts/spree/backend/solidus_subscriptions/edit_subscription_payment.js +32 -0
  17. data/app/controllers/solidus_subscriptions/api/v1/base_controller.rb +13 -0
  18. data/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb +48 -0
  19. data/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb +100 -0
  20. data/app/controllers/spree/admin/installments_controller.rb +25 -0
  21. data/app/controllers/spree/admin/subscription_events_controller.rb +37 -0
  22. data/app/controllers/spree/admin/subscription_orders_controller.rb +35 -0
  23. data/app/controllers/spree/admin/subscriptions_controller.rb +100 -0
  24. data/app/controllers/spree/admin/users/subscriptions_controller.rb +17 -0
  25. data/app/decorators/controllers/solidus_subscriptions/spree/api/line_items_controller/create_subscription_line_items.rb +36 -0
  26. data/app/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items.rb +35 -0
  27. data/app/decorators/models/solidus_subscriptions/spree/line_item/subscription_line_items_association.rb +26 -0
  28. data/app/decorators/models/solidus_subscriptions/spree/order/after_create.rb +19 -0
  29. data/app/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions.rb +23 -0
  30. data/app/decorators/models/solidus_subscriptions/spree/order/installment_details_association.rb +15 -0
  31. data/app/decorators/models/solidus_subscriptions/spree/order/subscription_association.rb +15 -0
  32. data/app/decorators/models/solidus_subscriptions/spree/order/subscription_line_items_association.rb +19 -0
  33. data/app/decorators/models/solidus_subscriptions/spree/product/delegate_subscribable.rb +17 -0
  34. data/app/decorators/models/solidus_subscriptions/spree/user/have_many_subscriptions.rb +30 -0
  35. data/app/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions.rb +20 -0
  36. data/app/decorators/models/solidus_subscriptions/spree/variant/variant_pretty_name.rb +17 -0
  37. data/app/decorators/models/solidus_subscriptions/spree/wallet_payment_source/report_default_change_to_subscriptions.rb +28 -0
  38. data/app/jobs/solidus_subscriptions/process_installment_job.rb +13 -0
  39. data/app/jobs/solidus_subscriptions/process_subscription_job.rb +31 -0
  40. data/app/models/solidus_subscriptions/installment.rb +135 -0
  41. data/app/models/solidus_subscriptions/installment_detail.rb +28 -0
  42. data/app/models/solidus_subscriptions/interval.rb +26 -0
  43. data/app/models/solidus_subscriptions/line_item.rb +42 -0
  44. data/app/models/solidus_subscriptions/promotion/rules/subscription_creation_order.rb +44 -0
  45. data/app/models/solidus_subscriptions/promotion/rules/subscription_installment_order.rb +31 -0
  46. data/app/models/solidus_subscriptions/subscription.rb +392 -0
  47. data/app/models/solidus_subscriptions/subscription_event.rb +11 -0
  48. data/app/overrides/views/admin_subscribable_product_checkbox.rb +8 -0
  49. data/app/overrides/views/admin_subscribable_variant_checkbox.rb +8 -0
  50. data/app/overrides/views/admin_subscriptions_menu_link.rb +10 -0
  51. data/app/overrides/views/admin_users_subscriptions_tab.rb +8 -0
  52. data/app/overrides/views/subscription_line_item_fields.rb +8 -0
  53. data/app/subscribers/solidus_subscriptions/churn_buster_subscriber.rb +39 -0
  54. data/app/subscribers/solidus_subscriptions/event_storage_subscriber.rb +64 -0
  55. data/app/views/spree/admin/installments/_state_pill.html.erb +8 -0
  56. data/app/views/spree/admin/installments/index.html.erb +42 -0
  57. data/app/views/spree/admin/products/_subscribable_checkbox.html.erb +8 -0
  58. data/app/views/spree/admin/promotions/rules/_subscription_creation_order.html.erb +0 -0
  59. data/app/views/spree/admin/promotions/rules/_subscription_installment_order.html.erb +0 -0
  60. data/app/views/spree/admin/shared/_subscription_actions.html.erb +35 -0
  61. data/app/views/spree/admin/shared/_subscription_breadcrumbs.html.erb +4 -0
  62. data/app/views/spree/admin/shared/_subscription_sidebar.html.erb +18 -0
  63. data/app/views/spree/admin/shared/_subscription_tab.html.erb +3 -0
  64. data/app/views/spree/admin/shared/_subscription_tabs.html.erb +18 -0
  65. data/app/views/spree/admin/subscription_events/_state_pill.html.erb +8 -0
  66. data/app/views/spree/admin/subscription_events/index.html.erb +42 -0
  67. data/app/views/spree/admin/subscription_orders/index.html.erb +93 -0
  68. data/app/views/spree/admin/subscriptions/_form.html.erb +150 -0
  69. data/app/views/spree/admin/subscriptions/_processing_state_pill.html.erb +9 -0
  70. data/app/views/spree/admin/subscriptions/_state_pill.html.erb +10 -0
  71. data/app/views/spree/admin/subscriptions/edit.html.erb +10 -0
  72. data/app/views/spree/admin/subscriptions/index.html.erb +176 -0
  73. data/app/views/spree/admin/subscriptions/new.html.erb +5 -0
  74. data/app/views/spree/admin/users/_subscription_tab.html.erb +5 -0
  75. data/app/views/spree/admin/users/subscriptions/index.html.erb +44 -0
  76. data/app/views/spree/admin/variants/_subscribable_checkbox.html.erb +6 -0
  77. data/app/views/spree/frontend/products/_subscription_line_item_fields.html.erb +30 -0
  78. data/bin/console +17 -0
  79. data/bin/rails +7 -0
  80. data/bin/rails-engine +13 -0
  81. data/bin/rails-sandbox +16 -0
  82. data/bin/rake +7 -0
  83. data/bin/sandbox +86 -0
  84. data/bin/setup +8 -0
  85. data/config/initializers/permission_sets.rb +11 -0
  86. data/config/initializers/subscribers.rb +9 -0
  87. data/config/locales/en.yml +129 -0
  88. data/config/routes.rb +34 -0
  89. data/db/migrate/20160825164850_create_solidus_subscriptions_subscriptions.rb +11 -0
  90. data/db/migrate/20160825173548_create_solidus_subscriptions_line_items.rb +17 -0
  91. data/db/migrate/20160825202248_create_solidus_subscriptions_installments.rb +23 -0
  92. data/db/migrate/20160825211202_create_solidus_subscriptions_installment_details.rb +22 -0
  93. data/db/migrate/20160825214240_add_subscribable_to_spree_variants.rb +5 -0
  94. data/db/migrate/20160829201653_change_subscription_line_items_installments_to_max_installments.rb +5 -0
  95. data/db/migrate/20160902220242_remove_state_from_solidus_susbscriptions_installment_details.rb +5 -0
  96. data/db/migrate/20160902220604_add_successful_to_solidus_subscriptions_installment_details.rb +5 -0
  97. data/db/migrate/20160902221218_add_message_to_solidus_subscriptions_installment_details.rb +5 -0
  98. data/db/migrate/20160922164101_add_interval_length_and_units_to_subscription_line_items.rb +8 -0
  99. data/db/migrate/20161006191003_add_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -0
  100. data/db/migrate/20161006191127_add_successive_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -0
  101. data/db/migrate/20161014212649_allow_spree_line_item_id_to_be_null.rb +5 -0
  102. data/db/migrate/20161017155749_add_order_id_to_solidus_subscriptions_installment_details.rb +6 -0
  103. data/db/migrate/20161017175509_remove_order_id_from_solidus_subscriptions_installments.rb +5 -0
  104. data/db/migrate/20161017201944_add_subscription_order_to_spree_orders.rb +5 -0
  105. data/db/migrate/20161221155142_add_store_to_solidus_subscriptions_subscriptions.rb +6 -0
  106. data/db/migrate/20161223152905_add_address_id_to_solidus_subscriptions_subscriptions.rb +7 -0
  107. data/db/migrate/20170106224713_change_line_item_max_installments_to_end_date.rb +6 -0
  108. data/db/migrate/20170111224458_change_subscription_actionable_date_to_datetime.rb +5 -0
  109. data/db/migrate/20170111232801_change_inteval_actionable_date_to_datetime.rb +5 -0
  110. data/db/migrate/20170112012407_add_config_options_to_subscriptions.rb +7 -0
  111. data/db/migrate/20200617102749_add_billing_address_to_subscriptions.rb +11 -0
  112. data/db/migrate/20200617155042_add_payment_source_to_subscriptions.rb +6 -0
  113. data/db/migrate/20200618092951_add_payment_method_to_subscriptions.rb +11 -0
  114. data/db/migrate/20200730101242_create_solidus_subscriptions_subscription_events.rb +22 -0
  115. data/db/migrate/20200917072152_add_subscription_reference_to_orders.rb +11 -0
  116. data/db/migrate/20201007140032_add_guest_token_to_subscriptions.rb +6 -0
  117. data/db/migrate/20201123171026_change_actionable_date_to_date.rb +15 -0
  118. data/db/migrate/20210205140422_add_currency_to_subscription.rb +5 -0
  119. data/db/migrate/20210323165714_update_promotion_rule_names.rb +22 -0
  120. data/lib/generators/solidus_subscriptions/install/install_generator.rb +32 -0
  121. data/lib/generators/solidus_subscriptions/install/templates/initializer.rb +99 -0
  122. data/lib/solidus_subscriptions.rb +49 -0
  123. data/lib/solidus_subscriptions/checkout.rb +74 -0
  124. data/lib/solidus_subscriptions/churn_buster/client.rb +48 -0
  125. data/lib/solidus_subscriptions/churn_buster/order_serializer.rb +19 -0
  126. data/lib/solidus_subscriptions/churn_buster/serializer.rb +23 -0
  127. data/lib/solidus_subscriptions/churn_buster/subscription_customer_serializer.rb +28 -0
  128. data/lib/solidus_subscriptions/churn_buster/subscription_payment_method_serializer.rb +37 -0
  129. data/lib/solidus_subscriptions/churn_buster/subscription_serializer.rb +17 -0
  130. data/lib/solidus_subscriptions/configuration.rb +84 -0
  131. data/lib/solidus_subscriptions/dispatcher/base.rb +18 -0
  132. data/lib/solidus_subscriptions/dispatcher/failure_dispatcher.rb +13 -0
  133. data/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher.rb +11 -0
  134. data/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher.rb +19 -0
  135. data/lib/solidus_subscriptions/dispatcher/success_dispatcher.rb +17 -0
  136. data/lib/solidus_subscriptions/engine.rb +56 -0
  137. data/lib/solidus_subscriptions/permission_sets/default_customer.rb +19 -0
  138. data/lib/solidus_subscriptions/permission_sets/subscription_management.rb +12 -0
  139. data/lib/solidus_subscriptions/permitted_attributes.rb +20 -0
  140. data/lib/solidus_subscriptions/processor.rb +17 -0
  141. data/lib/solidus_subscriptions/subscription_generator.rb +77 -0
  142. data/lib/solidus_subscriptions/subscription_line_item_builder.rb +23 -0
  143. data/lib/solidus_subscriptions/testing_support/factories/installment_detail_factory.rb +11 -0
  144. data/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb +29 -0
  145. data/lib/solidus_subscriptions/testing_support/factories/line_item_factory.rb +20 -0
  146. data/lib/solidus_subscriptions/testing_support/factories/spree/line_item_factory.rb +17 -0
  147. data/lib/solidus_subscriptions/testing_support/factories/spree/order_factory.rb +17 -0
  148. data/lib/solidus_subscriptions/testing_support/factories/spree_modification_factory.rb +10 -0
  149. data/lib/solidus_subscriptions/testing_support/factories/subscription_event_factory.rb +8 -0
  150. data/lib/solidus_subscriptions/testing_support/factories/subscription_factory.rb +56 -0
  151. data/lib/solidus_subscriptions/version.rb +5 -0
  152. data/lib/tasks/process_subscriptions.rake +8 -0
  153. data/reference/solidus_subscriptions.v1.yaml +290 -0
  154. data/solidus_subscriptions.gemspec +47 -0
  155. data/spec/controllers/spree/admin/subscriptions_controller_spec.rb +202 -0
  156. data/spec/controllers/spree/api/line_items_controller_spec.rb +103 -0
  157. data/spec/controllers/spree/api/orders_controller_spec.rb +57 -0
  158. data/spec/controllers/spree/api/users_controller_spec.rb +48 -0
  159. data/spec/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items_spec.rb +80 -0
  160. data/spec/decorators/models/solidus_subscriptions/spree/line_item/subscription_line_items_association_spec.rb +10 -0
  161. data/spec/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions_spec.rb +32 -0
  162. data/spec/decorators/models/solidus_subscriptions/spree/order/installment_details_association_spec.rb +9 -0
  163. data/spec/decorators/models/solidus_subscriptions/spree/order/subscription_line_items_association_spec.rb +9 -0
  164. data/spec/decorators/models/solidus_subscriptions/spree/user/have_many_subscriptions_spec.rb +22 -0
  165. data/spec/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions_spec.rb +25 -0
  166. data/spec/features/admin/subscription_orders_spec.rb +35 -0
  167. data/spec/features/admin/subscriptions_spec.rb +63 -0
  168. data/spec/features/admin_users_subscription_tabs_spec.rb +61 -0
  169. data/spec/fixtures/cassettes/churn_buster.yml +229 -0
  170. data/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb +38 -0
  171. data/spec/jobs/solidus_subscriptions/process_subscription_job_spec.rb +83 -0
  172. data/spec/lib/solidus_subscriptions/checkout_spec.rb +125 -0
  173. data/spec/lib/solidus_subscriptions/churn_buster/client_spec.rb +59 -0
  174. data/spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb +29 -0
  175. data/spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb +15 -0
  176. data/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb +44 -0
  177. data/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb +30 -0
  178. data/spec/lib/solidus_subscriptions/permission_sets/default_customer_spec.rb +95 -0
  179. data/spec/lib/solidus_subscriptions/permission_sets/subscription_management_spec.rb +26 -0
  180. data/spec/lib/solidus_subscriptions/processor_spec.rb +34 -0
  181. data/spec/lib/solidus_subscriptions/promotion/rules/subscription_creation_order_spec.rb +57 -0
  182. data/spec/lib/solidus_subscriptions/promotion/rules/subscription_installment_order_spec.rb +39 -0
  183. data/spec/lib/solidus_subscriptions/subscription_generator_spec.rb +83 -0
  184. data/spec/lib/solidus_subscriptions_spec.rb +30 -0
  185. data/spec/models/solidus_subscriptions/installment_detail_spec.rb +23 -0
  186. data/spec/models/solidus_subscriptions/installment_spec.rb +201 -0
  187. data/spec/models/solidus_subscriptions/line_item_spec.rb +29 -0
  188. data/spec/models/solidus_subscriptions/subscription_spec.rb +814 -0
  189. data/spec/models/spree/variant_spec.rb +16 -0
  190. data/spec/models/spree/wallet_payment_source_spec.rb +20 -0
  191. data/spec/requests/api/v1/line_items_spec.rb +116 -0
  192. data/spec/requests/api/v1/subscriptions_spec.rb +255 -0
  193. data/spec/spec_helper.rb +30 -0
  194. data/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb +76 -0
  195. data/spec/support/active_model_mocks.rb +1 -0
  196. data/spec/support/cancancan.rb +1 -0
  197. data/spec/support/factories.rb +1 -0
  198. data/spec/support/helpers/checkout_infrastructure.rb +18 -0
  199. data/spec/support/helpers/config.rb +13 -0
  200. data/spec/support/shoulda.rb +7 -0
  201. data/spec/support/timecop.rb +1 -0
  202. data/spec/support/vcr.rb +10 -0
  203. data/spec/support/version_cake.rb +8 -0
  204. metadata +498 -0
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Admin
5
+ class SubscriptionEventsController < ResourceController
6
+ belongs_to 'subscription', model_class: SolidusSubscriptions::Subscription
7
+
8
+ skip_before_action :load_resource, only: :index
9
+
10
+ def index
11
+ @search = collection.ransack((params[:q] || {}).reverse_merge(s: 'created_at desc'))
12
+
13
+ @subscription_events = @search.result(distinct: true).
14
+ page(params[:page]).
15
+ per(params[:per_page] || 20)
16
+ end
17
+
18
+ private
19
+
20
+ def model_class
21
+ ::SolidusSubscriptions::SubscriptionEvent
22
+ end
23
+
24
+ def find_resource
25
+ parent.events.find(params[:id])
26
+ end
27
+
28
+ def build_resource
29
+ parent.events.build
30
+ end
31
+
32
+ def collection
33
+ parent.events
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Admin
5
+ class SubscriptionOrdersController < ResourceController
6
+ belongs_to 'subscription', model_class: SolidusSubscriptions::Subscription
7
+
8
+ def index
9
+ @search = collection.ransack((params[:q] || {}).reverse_merge(s: 'created_at desc'))
10
+
11
+ @subscription_orders = @search.result(distinct: true).
12
+ page(params[:page]).
13
+ per(params[:per_page] || 20)
14
+ end
15
+
16
+ private
17
+
18
+ def model_class
19
+ ::Spree::Order
20
+ end
21
+
22
+ def find_resource
23
+ parent.orders.find(params[:id])
24
+ end
25
+
26
+ def build_resource
27
+ parent.orders.build
28
+ end
29
+
30
+ def collection
31
+ parent.orders
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Admin
5
+ class SubscriptionsController < ResourceController
6
+ skip_before_action :load_resource, only: :index
7
+
8
+ def index
9
+ @search = SolidusSubscriptions::Subscription.accessible_by(current_ability).ransack(params[:q])
10
+ @subscriptions = @search.result(distinct: true).
11
+ includes(:line_items, :user).
12
+ page(params[:page]).
13
+ per(params[:per_page] || Spree::Config[:orders_per_page])
14
+ end
15
+
16
+ def new
17
+ prepare_form
18
+ end
19
+
20
+ def edit
21
+ prepare_form
22
+ load_payment_methods
23
+ end
24
+
25
+ def update
26
+ load_payment_methods
27
+ @subscription.payment_method_id = params[:subscription][:payment_method_id]
28
+
29
+ if @subscription.payment_method&.source_required?
30
+ @subscription.payment_source = @subscription
31
+ .payment_method
32
+ .payment_source_class
33
+ .find_by(id: params[:subscription][:payment_source_id])
34
+ else
35
+ @subscription.payment_source = nil
36
+ end
37
+
38
+ super
39
+ end
40
+
41
+ def cancel
42
+ @subscription.transaction do
43
+ @subscription.actionable_date = nil
44
+ @subscription.cancel
45
+ end
46
+
47
+ notice = if @subscription.errors.none?
48
+ I18n.t('spree.admin.subscriptions.successfully_canceled')
49
+ else
50
+ @subscription.errors.full_messages.to_sentence
51
+ end
52
+
53
+ redirect_back(fallback_location: spree.admin_subscriptions_path, notice: notice)
54
+ end
55
+
56
+ def activate
57
+ @subscription.activate
58
+
59
+ notice = if @subscription.errors.none?
60
+ I18n.t('spree.admin.subscriptions.successfully_activated')
61
+ else
62
+ @subscription.errors.full_messages.to_sentence
63
+ end
64
+
65
+ redirect_back(fallback_location: spree.admin_subscriptions_path, notice: notice)
66
+ end
67
+
68
+ def skip
69
+ @subscription.skip(check_skip_limits: false)
70
+
71
+ notice = I18n.t(
72
+ 'spree.admin.subscriptions.successfully_skipped',
73
+ date: @subscription.actionable_date
74
+ )
75
+
76
+ redirect_back(fallback_location: spree.admin_subscriptions_path, notice: notice)
77
+ end
78
+
79
+ private
80
+
81
+ def model_class
82
+ ::SolidusSubscriptions::Subscription
83
+ end
84
+
85
+ def location_after_save
86
+ edit_object_url(@subscription)
87
+ end
88
+
89
+ def prepare_form
90
+ @subscription.build_shipping_address(@subscription.shipping_address&.value_attributes)
91
+ @subscription.build_billing_address(@subscription.billing_address&.value_attributes)
92
+ @subscription.line_items.build
93
+ end
94
+
95
+ def load_payment_methods
96
+ @payment_methods = Spree::PaymentMethod.active.available_to_admin.ordered_by_position
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Admin
5
+ module Users
6
+ class SubscriptionsController < ResourceController
7
+ belongs_to 'spree/user', model_class: Spree.user_class
8
+
9
+ private
10
+
11
+ def model_class
12
+ ::SolidusSubscriptions::Subscription
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create new subscription line items associated to the current order, when
4
+ # a line item is added to the cart which includes subscription_line_item
5
+ # params.
6
+ #
7
+ # The Subscriptions::LineItem acts as a line item place holder for a
8
+ # Subscription, indicating that it has been added to the order, but not
9
+ # yet purchased
10
+ module SolidusSubscriptions
11
+ module Spree
12
+ module Api
13
+ module LineItemsController
14
+ module CreateSubscriptionLineItems
15
+ include SolidusSubscriptions::SubscriptionLineItemBuilder
16
+
17
+ def self.prepended(base)
18
+ base.after_action(
19
+ :handle_subscription_line_items,
20
+ only: [:create, :update],
21
+ if: ->{ params[:subscription_line_item] }
22
+ )
23
+ end
24
+
25
+ private
26
+
27
+ def handle_subscription_line_items
28
+ create_subscription_line_item(@line_item)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ Spree::Api::LineItemsController.prepend(SolidusSubscriptions::Spree::Api::LineItemsController::CreateSubscriptionLineItems)
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create new subscription line items associated to the current order, when
4
+ # a line item is added to the cart which includes subscription_line_item
5
+ # params.
6
+ #
7
+ # The Subscriptions::LineItem acts as a line item place holder for a
8
+ # Subscription, indicating that it has been added to the order, but not
9
+ # yet purchased
10
+ module SolidusSubscriptions
11
+ module Spree
12
+ module OrdersController
13
+ module CreateSubscriptionLineItems
14
+ include SolidusSubscriptions::SubscriptionLineItemBuilder
15
+
16
+ def self.prepended(base)
17
+ base.after_action(
18
+ :handle_subscription_line_items,
19
+ only: :populate,
20
+ if: ->{ params[:subscription_line_item] }
21
+ )
22
+ end
23
+
24
+ private
25
+
26
+ def handle_subscription_line_items
27
+ line_item = @current_order.line_items.find_by(variant_id: params[:variant_id])
28
+ create_subscription_line_item(line_item)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ Spree::OrdersController.prepend(SolidusSubscriptions::Spree::OrdersController::CreateSubscriptionLineItems)
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Each Spree::LineItem can have multiple subscription_line_items. This
4
+ # allows a cart to represent multiple subscriptions to the same item in
5
+ # the same order.
6
+ module SolidusSubscriptions
7
+ module Spree
8
+ module LineItem
9
+ module SubscriptionLineItemsAssociation
10
+ def self.prepended(base)
11
+ base.has_many(
12
+ :subscription_line_items,
13
+ class_name: 'SolidusSubscriptions::LineItem',
14
+ foreign_key: :spree_line_item_id,
15
+ inverse_of: :spree_line_item,
16
+ dependent: :destroy
17
+ )
18
+
19
+ base.accepts_nested_attributes_for :subscription_line_items
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ Spree::LineItem.prepend(SolidusSubscriptions::Spree::LineItem::SubscriptionLineItemsAssociation)
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSubscriptions
4
+ module Spree
5
+ module Order
6
+ module AfterCreate
7
+ def ensure_line_items_present
8
+ super unless subscription_order?
9
+ end
10
+
11
+ def send_cancel_email
12
+ super unless subscription_order?
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Spree::Order.prepend(SolidusSubscriptions::Spree::Order::AfterCreate)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Once an order is finalized its subscriptions line items should be converted
4
+ # into active subscriptions. This hooks into Spree::Order#finalize! and
5
+ # passes all subscription_line_items present on the order to the Subscription
6
+ # generator which will build and persist the subscriptions
7
+ module SolidusSubscriptions
8
+ module Spree
9
+ module Order
10
+ module FinalizeCreatesSubscriptions
11
+ def finalize!
12
+ SolidusSubscriptions::SubscriptionGenerator.group(subscription_line_items).each do |line_items|
13
+ SolidusSubscriptions::SubscriptionGenerator.activate(line_items)
14
+ end
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Spree::Order.prepend(SolidusSubscriptions::Spree::Order::FinalizeCreatesSubscriptions)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSubscriptions
4
+ module Spree
5
+ module Order
6
+ module InstallmentDetailsAssociation
7
+ def self.prepended(base)
8
+ base.has_many :installment_details, class_name: '::SolidusSubscriptions::InstallmentDetail'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Spree::Order.prepend(SolidusSubscriptions::Spree::Order::InstallmentDetailsAssociation)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSubscriptions
4
+ module Spree
5
+ module Order
6
+ module SubscriptionAssociation
7
+ def self.prepended(base)
8
+ base.belongs_to :subscription, class_name: '::SolidusSubscriptions::Subscription', optional: true
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Spree::Order.prepend(SolidusSubscriptions::Spree::Order::SubscriptionAssociation)
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Spree::Orders may contain many subscription_line_items. When the order is
4
+ # finalized these subscription_line_items are converted into subscritpions.
5
+ # The order needs to be able to get a list of associated subscription_line_items
6
+ # to be able to populate the full subscriptions.
7
+ module SolidusSubscriptions
8
+ module Spree
9
+ module Order
10
+ module SubscriptionLineItemsAssociation
11
+ def self.prepended(base)
12
+ base.has_many :subscription_line_items, through: :line_items
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Spree::Order.prepend(SolidusSubscriptions::Spree::Order::SubscriptionLineItemsAssociation)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSubscriptions
4
+ module Spree
5
+ module Product
6
+ module DelegateSubscribable
7
+ def self.prepended(base)
8
+ base.class_eval do
9
+ delegate :subscribable, :subscribable=, to: :find_or_build_master
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ Spree::Product.prepend(SolidusSubscriptions::Spree::Product::DelegateSubscribable)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Spree::Users maintain a list of the subscriptions associated with them
4
+ module SolidusSubscriptions
5
+ module Spree
6
+ module User
7
+ module HaveManySubscriptions
8
+ def self.prepended(base)
9
+ base.has_many(
10
+ :subscriptions,
11
+ class_name: 'SolidusSubscriptions::Subscription',
12
+ foreign_key: 'user_id'
13
+ )
14
+
15
+ base.accepts_nested_attributes_for :subscriptions
16
+ end
17
+
18
+ def subscriptions_attributes=(params)
19
+ ::Spree::Deprecation.warn(
20
+ 'Creating or updating subscriptions through Spree::User nested attributes is deprecated. ' \
21
+ 'Please use subscriptions APIs directly.'
22
+ )
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ Spree.user_class.prepend(SolidusSubscriptions::Spree::User::HaveManySubscriptions)