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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +41 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.github_changelog_generator +2 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +12 -0
- data/.rubocop_todo.yml +86 -0
- data/CHANGELOG.md +191 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +221 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_subscriptions.js +1 -0
- data/app/assets/javascripts/spree/backend/solidus_subscriptions/edit_subscription_payment.js +32 -0
- data/app/controllers/solidus_subscriptions/api/v1/base_controller.rb +13 -0
- data/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb +48 -0
- data/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb +100 -0
- data/app/controllers/spree/admin/installments_controller.rb +25 -0
- data/app/controllers/spree/admin/subscription_events_controller.rb +37 -0
- data/app/controllers/spree/admin/subscription_orders_controller.rb +35 -0
- data/app/controllers/spree/admin/subscriptions_controller.rb +100 -0
- data/app/controllers/spree/admin/users/subscriptions_controller.rb +17 -0
- data/app/decorators/controllers/solidus_subscriptions/spree/api/line_items_controller/create_subscription_line_items.rb +36 -0
- data/app/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items.rb +35 -0
- data/app/decorators/models/solidus_subscriptions/spree/line_item/subscription_line_items_association.rb +26 -0
- data/app/decorators/models/solidus_subscriptions/spree/order/after_create.rb +19 -0
- data/app/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions.rb +23 -0
- data/app/decorators/models/solidus_subscriptions/spree/order/installment_details_association.rb +15 -0
- data/app/decorators/models/solidus_subscriptions/spree/order/subscription_association.rb +15 -0
- data/app/decorators/models/solidus_subscriptions/spree/order/subscription_line_items_association.rb +19 -0
- data/app/decorators/models/solidus_subscriptions/spree/product/delegate_subscribable.rb +17 -0
- data/app/decorators/models/solidus_subscriptions/spree/user/have_many_subscriptions.rb +30 -0
- data/app/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions.rb +20 -0
- data/app/decorators/models/solidus_subscriptions/spree/variant/variant_pretty_name.rb +17 -0
- data/app/decorators/models/solidus_subscriptions/spree/wallet_payment_source/report_default_change_to_subscriptions.rb +28 -0
- data/app/jobs/solidus_subscriptions/process_installment_job.rb +13 -0
- data/app/jobs/solidus_subscriptions/process_subscription_job.rb +31 -0
- data/app/models/solidus_subscriptions/installment.rb +135 -0
- data/app/models/solidus_subscriptions/installment_detail.rb +28 -0
- data/app/models/solidus_subscriptions/interval.rb +26 -0
- data/app/models/solidus_subscriptions/line_item.rb +42 -0
- data/app/models/solidus_subscriptions/promotion/rules/subscription_creation_order.rb +44 -0
- data/app/models/solidus_subscriptions/promotion/rules/subscription_installment_order.rb +31 -0
- data/app/models/solidus_subscriptions/subscription.rb +392 -0
- data/app/models/solidus_subscriptions/subscription_event.rb +11 -0
- data/app/overrides/views/admin_subscribable_product_checkbox.rb +8 -0
- data/app/overrides/views/admin_subscribable_variant_checkbox.rb +8 -0
- data/app/overrides/views/admin_subscriptions_menu_link.rb +10 -0
- data/app/overrides/views/admin_users_subscriptions_tab.rb +8 -0
- data/app/overrides/views/subscription_line_item_fields.rb +8 -0
- data/app/subscribers/solidus_subscriptions/churn_buster_subscriber.rb +39 -0
- data/app/subscribers/solidus_subscriptions/event_storage_subscriber.rb +64 -0
- data/app/views/spree/admin/installments/_state_pill.html.erb +8 -0
- data/app/views/spree/admin/installments/index.html.erb +42 -0
- data/app/views/spree/admin/products/_subscribable_checkbox.html.erb +8 -0
- data/app/views/spree/admin/promotions/rules/_subscription_creation_order.html.erb +0 -0
- data/app/views/spree/admin/promotions/rules/_subscription_installment_order.html.erb +0 -0
- data/app/views/spree/admin/shared/_subscription_actions.html.erb +35 -0
- data/app/views/spree/admin/shared/_subscription_breadcrumbs.html.erb +4 -0
- data/app/views/spree/admin/shared/_subscription_sidebar.html.erb +18 -0
- data/app/views/spree/admin/shared/_subscription_tab.html.erb +3 -0
- data/app/views/spree/admin/shared/_subscription_tabs.html.erb +18 -0
- data/app/views/spree/admin/subscription_events/_state_pill.html.erb +8 -0
- data/app/views/spree/admin/subscription_events/index.html.erb +42 -0
- data/app/views/spree/admin/subscription_orders/index.html.erb +93 -0
- data/app/views/spree/admin/subscriptions/_form.html.erb +150 -0
- data/app/views/spree/admin/subscriptions/_processing_state_pill.html.erb +9 -0
- data/app/views/spree/admin/subscriptions/_state_pill.html.erb +10 -0
- data/app/views/spree/admin/subscriptions/edit.html.erb +10 -0
- data/app/views/spree/admin/subscriptions/index.html.erb +176 -0
- data/app/views/spree/admin/subscriptions/new.html.erb +5 -0
- data/app/views/spree/admin/users/_subscription_tab.html.erb +5 -0
- data/app/views/spree/admin/users/subscriptions/index.html.erb +44 -0
- data/app/views/spree/admin/variants/_subscribable_checkbox.html.erb +6 -0
- data/app/views/spree/frontend/products/_subscription_line_item_fields.html.erb +30 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +86 -0
- data/bin/setup +8 -0
- data/config/initializers/permission_sets.rb +11 -0
- data/config/initializers/subscribers.rb +9 -0
- data/config/locales/en.yml +129 -0
- data/config/routes.rb +34 -0
- data/db/migrate/20160825164850_create_solidus_subscriptions_subscriptions.rb +11 -0
- data/db/migrate/20160825173548_create_solidus_subscriptions_line_items.rb +17 -0
- data/db/migrate/20160825202248_create_solidus_subscriptions_installments.rb +23 -0
- data/db/migrate/20160825211202_create_solidus_subscriptions_installment_details.rb +22 -0
- data/db/migrate/20160825214240_add_subscribable_to_spree_variants.rb +5 -0
- data/db/migrate/20160829201653_change_subscription_line_items_installments_to_max_installments.rb +5 -0
- data/db/migrate/20160902220242_remove_state_from_solidus_susbscriptions_installment_details.rb +5 -0
- data/db/migrate/20160902220604_add_successful_to_solidus_subscriptions_installment_details.rb +5 -0
- data/db/migrate/20160902221218_add_message_to_solidus_subscriptions_installment_details.rb +5 -0
- data/db/migrate/20160922164101_add_interval_length_and_units_to_subscription_line_items.rb +8 -0
- data/db/migrate/20161006191003_add_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -0
- data/db/migrate/20161006191127_add_successive_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -0
- data/db/migrate/20161014212649_allow_spree_line_item_id_to_be_null.rb +5 -0
- data/db/migrate/20161017155749_add_order_id_to_solidus_subscriptions_installment_details.rb +6 -0
- data/db/migrate/20161017175509_remove_order_id_from_solidus_subscriptions_installments.rb +5 -0
- data/db/migrate/20161017201944_add_subscription_order_to_spree_orders.rb +5 -0
- data/db/migrate/20161221155142_add_store_to_solidus_subscriptions_subscriptions.rb +6 -0
- data/db/migrate/20161223152905_add_address_id_to_solidus_subscriptions_subscriptions.rb +7 -0
- data/db/migrate/20170106224713_change_line_item_max_installments_to_end_date.rb +6 -0
- data/db/migrate/20170111224458_change_subscription_actionable_date_to_datetime.rb +5 -0
- data/db/migrate/20170111232801_change_inteval_actionable_date_to_datetime.rb +5 -0
- data/db/migrate/20170112012407_add_config_options_to_subscriptions.rb +7 -0
- data/db/migrate/20200617102749_add_billing_address_to_subscriptions.rb +11 -0
- data/db/migrate/20200617155042_add_payment_source_to_subscriptions.rb +6 -0
- data/db/migrate/20200618092951_add_payment_method_to_subscriptions.rb +11 -0
- data/db/migrate/20200730101242_create_solidus_subscriptions_subscription_events.rb +22 -0
- data/db/migrate/20200917072152_add_subscription_reference_to_orders.rb +11 -0
- data/db/migrate/20201007140032_add_guest_token_to_subscriptions.rb +6 -0
- data/db/migrate/20201123171026_change_actionable_date_to_date.rb +15 -0
- data/db/migrate/20210205140422_add_currency_to_subscription.rb +5 -0
- data/db/migrate/20210323165714_update_promotion_rule_names.rb +22 -0
- data/lib/generators/solidus_subscriptions/install/install_generator.rb +32 -0
- data/lib/generators/solidus_subscriptions/install/templates/initializer.rb +99 -0
- data/lib/solidus_subscriptions.rb +49 -0
- data/lib/solidus_subscriptions/checkout.rb +74 -0
- data/lib/solidus_subscriptions/churn_buster/client.rb +48 -0
- data/lib/solidus_subscriptions/churn_buster/order_serializer.rb +19 -0
- data/lib/solidus_subscriptions/churn_buster/serializer.rb +23 -0
- data/lib/solidus_subscriptions/churn_buster/subscription_customer_serializer.rb +28 -0
- data/lib/solidus_subscriptions/churn_buster/subscription_payment_method_serializer.rb +37 -0
- data/lib/solidus_subscriptions/churn_buster/subscription_serializer.rb +17 -0
- data/lib/solidus_subscriptions/configuration.rb +84 -0
- data/lib/solidus_subscriptions/dispatcher/base.rb +18 -0
- data/lib/solidus_subscriptions/dispatcher/failure_dispatcher.rb +13 -0
- data/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher.rb +11 -0
- data/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher.rb +19 -0
- data/lib/solidus_subscriptions/dispatcher/success_dispatcher.rb +17 -0
- data/lib/solidus_subscriptions/engine.rb +56 -0
- data/lib/solidus_subscriptions/permission_sets/default_customer.rb +19 -0
- data/lib/solidus_subscriptions/permission_sets/subscription_management.rb +12 -0
- data/lib/solidus_subscriptions/permitted_attributes.rb +20 -0
- data/lib/solidus_subscriptions/processor.rb +17 -0
- data/lib/solidus_subscriptions/subscription_generator.rb +77 -0
- data/lib/solidus_subscriptions/subscription_line_item_builder.rb +23 -0
- data/lib/solidus_subscriptions/testing_support/factories/installment_detail_factory.rb +11 -0
- data/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb +29 -0
- data/lib/solidus_subscriptions/testing_support/factories/line_item_factory.rb +20 -0
- data/lib/solidus_subscriptions/testing_support/factories/spree/line_item_factory.rb +17 -0
- data/lib/solidus_subscriptions/testing_support/factories/spree/order_factory.rb +17 -0
- data/lib/solidus_subscriptions/testing_support/factories/spree_modification_factory.rb +10 -0
- data/lib/solidus_subscriptions/testing_support/factories/subscription_event_factory.rb +8 -0
- data/lib/solidus_subscriptions/testing_support/factories/subscription_factory.rb +56 -0
- data/lib/solidus_subscriptions/version.rb +5 -0
- data/lib/tasks/process_subscriptions.rake +8 -0
- data/reference/solidus_subscriptions.v1.yaml +290 -0
- data/solidus_subscriptions.gemspec +47 -0
- data/spec/controllers/spree/admin/subscriptions_controller_spec.rb +202 -0
- data/spec/controllers/spree/api/line_items_controller_spec.rb +103 -0
- data/spec/controllers/spree/api/orders_controller_spec.rb +57 -0
- data/spec/controllers/spree/api/users_controller_spec.rb +48 -0
- data/spec/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items_spec.rb +80 -0
- data/spec/decorators/models/solidus_subscriptions/spree/line_item/subscription_line_items_association_spec.rb +10 -0
- data/spec/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions_spec.rb +32 -0
- data/spec/decorators/models/solidus_subscriptions/spree/order/installment_details_association_spec.rb +9 -0
- data/spec/decorators/models/solidus_subscriptions/spree/order/subscription_line_items_association_spec.rb +9 -0
- data/spec/decorators/models/solidus_subscriptions/spree/user/have_many_subscriptions_spec.rb +22 -0
- data/spec/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions_spec.rb +25 -0
- data/spec/features/admin/subscription_orders_spec.rb +35 -0
- data/spec/features/admin/subscriptions_spec.rb +63 -0
- data/spec/features/admin_users_subscription_tabs_spec.rb +61 -0
- data/spec/fixtures/cassettes/churn_buster.yml +229 -0
- data/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb +38 -0
- data/spec/jobs/solidus_subscriptions/process_subscription_job_spec.rb +83 -0
- data/spec/lib/solidus_subscriptions/checkout_spec.rb +125 -0
- data/spec/lib/solidus_subscriptions/churn_buster/client_spec.rb +59 -0
- data/spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb +29 -0
- data/spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb +15 -0
- data/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb +44 -0
- data/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb +30 -0
- data/spec/lib/solidus_subscriptions/permission_sets/default_customer_spec.rb +95 -0
- data/spec/lib/solidus_subscriptions/permission_sets/subscription_management_spec.rb +26 -0
- data/spec/lib/solidus_subscriptions/processor_spec.rb +34 -0
- data/spec/lib/solidus_subscriptions/promotion/rules/subscription_creation_order_spec.rb +57 -0
- data/spec/lib/solidus_subscriptions/promotion/rules/subscription_installment_order_spec.rb +39 -0
- data/spec/lib/solidus_subscriptions/subscription_generator_spec.rb +83 -0
- data/spec/lib/solidus_subscriptions_spec.rb +30 -0
- data/spec/models/solidus_subscriptions/installment_detail_spec.rb +23 -0
- data/spec/models/solidus_subscriptions/installment_spec.rb +201 -0
- data/spec/models/solidus_subscriptions/line_item_spec.rb +29 -0
- data/spec/models/solidus_subscriptions/subscription_spec.rb +814 -0
- data/spec/models/spree/variant_spec.rb +16 -0
- data/spec/models/spree/wallet_payment_source_spec.rb +20 -0
- data/spec/requests/api/v1/line_items_spec.rb +116 -0
- data/spec/requests/api/v1/subscriptions_spec.rb +255 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb +76 -0
- data/spec/support/active_model_mocks.rb +1 -0
- data/spec/support/cancancan.rb +1 -0
- data/spec/support/factories.rb +1 -0
- data/spec/support/helpers/checkout_infrastructure.rb +18 -0
- data/spec/support/helpers/config.rb +13 -0
- data/spec/support/shoulda.rb +7 -0
- data/spec/support/timecop.rb +1 -0
- data/spec/support/vcr.rb +10 -0
- data/spec/support/version_cake.rb +8 -0
- metadata +498 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class AddIntervalLengthAndUnitsToSubscriptionLineItems < SolidusSupport::Migration[4.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :solidus_subscriptions_line_items, :interval_units, :integer
|
|
4
|
+
add_column :solidus_subscriptions_line_items, :interval_length, :integer
|
|
5
|
+
|
|
6
|
+
remove_column :solidus_subscriptions_line_items, :interval
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class AddOrderIdToSolidusSubscriptionsInstallmentDetails < SolidusSupport::Migration[4.2]
|
|
2
|
+
def change
|
|
3
|
+
add_reference :solidus_subscriptions_installment_details, :order, index: true
|
|
4
|
+
add_foreign_key :solidus_subscriptions_installment_details, :spree_orders, column: :order_id
|
|
5
|
+
end
|
|
6
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class AddStoreToSolidusSubscriptionsSubscriptions < SolidusSupport::Migration[4.2]
|
|
2
|
+
def change
|
|
3
|
+
add_reference :solidus_subscriptions_subscriptions, :store, index: true
|
|
4
|
+
add_foreign_key :solidus_subscriptions_subscriptions, :spree_stores, column: :store_id
|
|
5
|
+
end
|
|
6
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class AddAddressIdToSolidusSubscriptionsSubscriptions < SolidusSupport::Migration[4.2]
|
|
2
|
+
def change
|
|
3
|
+
add_reference :solidus_subscriptions_subscriptions, :shipping_address
|
|
4
|
+
add_index :solidus_subscriptions_subscriptions, :shipping_address_id, name: :index_subscription_shipping_address_id
|
|
5
|
+
add_foreign_key :solidus_subscriptions_subscriptions, :spree_addresses, column: :shipping_address_id
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class AddConfigOptionsToSubscriptions < SolidusSupport::Migration[4.2]
|
|
2
|
+
def change
|
|
3
|
+
add_column :solidus_subscriptions_subscriptions, :interval_length, :integer
|
|
4
|
+
add_column :solidus_subscriptions_subscriptions, :interval_units, :integer
|
|
5
|
+
add_column :solidus_subscriptions_subscriptions, :end_date, :datetime
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class AddBillingAddressToSubscriptions < ActiveRecord::Migration[5.2]
|
|
2
|
+
def change
|
|
3
|
+
add_reference(
|
|
4
|
+
:solidus_subscriptions_subscriptions,
|
|
5
|
+
:billing_address,
|
|
6
|
+
type: :integer,
|
|
7
|
+
index: { name: :index_subscription_billing_address_id },
|
|
8
|
+
foreign_key: { to_table: :spree_addresses }
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class AddPaymentMethodToSubscriptions < ActiveRecord::Migration[5.2]
|
|
2
|
+
def change
|
|
3
|
+
add_reference(
|
|
4
|
+
:solidus_subscriptions_subscriptions,
|
|
5
|
+
:payment_method,
|
|
6
|
+
type: :integer,
|
|
7
|
+
index: { name: :index_subscription_payment_method_id },
|
|
8
|
+
foreign_key: { to_table: :spree_payment_methods }
|
|
9
|
+
)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class CreateSolidusSubscriptionsSubscriptionEvents < ActiveRecord::Migration[5.2]
|
|
2
|
+
def change
|
|
3
|
+
create_table :solidus_subscriptions_subscription_events do |t|
|
|
4
|
+
t.belongs_to(
|
|
5
|
+
:subscription,
|
|
6
|
+
null: false,
|
|
7
|
+
foreign_key: { to_table: :solidus_subscriptions_subscriptions },
|
|
8
|
+
index: { name: :idx_solidus_subscription_events_on_subscription_id },
|
|
9
|
+
type: :integer,
|
|
10
|
+
)
|
|
11
|
+
t.string :event_type, null: false
|
|
12
|
+
|
|
13
|
+
if t.respond_to?(:jsonb)
|
|
14
|
+
t.jsonb :details, null: false
|
|
15
|
+
else
|
|
16
|
+
t.json :details, null: false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class ChangeActionableDateToDate < ActiveRecord::Migration[5.2]
|
|
2
|
+
def change
|
|
3
|
+
reversible do |dir|
|
|
4
|
+
dir.up do
|
|
5
|
+
change_column :solidus_subscriptions_subscriptions, :actionable_date, :date
|
|
6
|
+
change_column :solidus_subscriptions_installments, :actionable_date, :date
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
dir.down do
|
|
10
|
+
change_column :solidus_subscriptions_subscriptions, :actionable_date, :datetime
|
|
11
|
+
change_column :solidus_subscriptions_installments, :actionable_date, :datetime
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class UpdatePromotionRuleNames < ActiveRecord::Migration[5.2]
|
|
2
|
+
TYPE_RENAMES = {
|
|
3
|
+
'SolidusSubscriptions::SubscriptionPromotionRule' => 'SolidusSubscriptions::Promotion::Rules::SubscriptionCreationOrder',
|
|
4
|
+
'SolidusSubscriptions::SubscriptionOrderPromotionRule' => 'SolidusSubscriptions::Promotion::Rules::SubscriptionInstallmentOrder',
|
|
5
|
+
}.freeze
|
|
6
|
+
|
|
7
|
+
def change
|
|
8
|
+
reversible do |dir|
|
|
9
|
+
dir.up do
|
|
10
|
+
TYPE_RENAMES.each do |old_type, new_type|
|
|
11
|
+
Spree::PromotionRule.where(type: old_type).update(type: new_type)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
dir.down do
|
|
16
|
+
TYPE_RENAMES.each do |old_type, new_type|
|
|
17
|
+
Spree::PromotionRule.where(type: new_type).update(type: old_type)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusSubscriptions
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
|
7
|
+
|
|
8
|
+
class_option :auto_run_migrations, type: :boolean, default: false
|
|
9
|
+
|
|
10
|
+
def copy_initializer
|
|
11
|
+
template 'initializer.rb', 'config/initializers/solidus_subscriptions.rb'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def add_javascripts
|
|
15
|
+
append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_subscriptions\n"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add_migrations
|
|
19
|
+
run 'bin/rails railties:install:migrations FROM=solidus_subscriptions'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run_migrations
|
|
23
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
|
|
24
|
+
if run_migrations
|
|
25
|
+
run 'bin/rails db:migrate'
|
|
26
|
+
else
|
|
27
|
+
puts 'Skipping bin/rails db:migrate, don\'t forget to run it!' # rubocop:disable Rails/Output
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SolidusSubscriptions.configure do |config|
|
|
4
|
+
# ========================================= Basic config =========================================
|
|
5
|
+
|
|
6
|
+
# The ActiveRecord model users can subscribe to.
|
|
7
|
+
# config.subscribable_class = 'Spree::Variant'
|
|
8
|
+
|
|
9
|
+
# Which queue is responsible for processing subscription background jobs.
|
|
10
|
+
# config.processing_queue = :default
|
|
11
|
+
|
|
12
|
+
# Maximum number of times a user can skip their subscription before it must be processed.
|
|
13
|
+
# config.maximum_successive_skips = 1
|
|
14
|
+
|
|
15
|
+
# Maximum number of times a user can skip their subscription.
|
|
16
|
+
# config.maximum_total_skips = nil
|
|
17
|
+
|
|
18
|
+
# Minimum days between the current date and the next installment for the installment not to be
|
|
19
|
+
# processed after the user cancels their subscription.
|
|
20
|
+
# config.minimum_cancellation_notice = 1.day
|
|
21
|
+
|
|
22
|
+
# Time between an installment failing to be processed and the system retrying to fulfill it.
|
|
23
|
+
# config.reprocessing_interval = 1.day
|
|
24
|
+
|
|
25
|
+
# Maximum time that can pass after the last succesfull subscription installment to make a payment
|
|
26
|
+
# failure cancel the subscription.
|
|
27
|
+
# config.maximum_reprocessing_time = nil
|
|
28
|
+
|
|
29
|
+
# This custom error handler is called when a ProcessInstallmentJob `#perform` method fails.
|
|
30
|
+
# The rescued error can be managed as required via a Proc, such as one which logs the error
|
|
31
|
+
# on an error tracking system.
|
|
32
|
+
# Though not recommended due to the retry mechanisms built into this gem, the error can be
|
|
33
|
+
# re-raised if the default retry behaviour is required in ActiveJob.
|
|
34
|
+
# config.processing_error_handler = nil
|
|
35
|
+
|
|
36
|
+
# ========================================= Dispatchers ==========================================
|
|
37
|
+
#
|
|
38
|
+
# These dispatchers are pluggable. If you override any handlers, it is highly encouraged that you
|
|
39
|
+
# subclass from the the dispatcher you are replacing and call `super` from within `#dispatch`.
|
|
40
|
+
|
|
41
|
+
# This handler is called when a subscription order is successfully placed.
|
|
42
|
+
# config.success_dispatcher_class = 'SolidusSubscriptions::Dispatcher::SuccessDispatcher'
|
|
43
|
+
|
|
44
|
+
# This handler is called when a group of installments fails to be processed.
|
|
45
|
+
# config.failure_dispatcher_class = 'SolidusSubscriptions::Dispatcher::FailureDispatcher'
|
|
46
|
+
|
|
47
|
+
# This handler is called when a payment fails on a subscription order.
|
|
48
|
+
# config.payment_failed_dispatcher_class = 'SolidusSubscriptions::Dispatcher::PaymentFailedDispatcher'
|
|
49
|
+
|
|
50
|
+
# This handler is called when there isn't enough stock to fulfill an installment.
|
|
51
|
+
# config.out_of_stock_dispatcher = 'SolidusSubscriptions::Dispatcher::OutOfStockDispatcher'
|
|
52
|
+
|
|
53
|
+
# ===================================== Permitted attributes =====================================
|
|
54
|
+
#
|
|
55
|
+
# In this section, you can override the list of attributes the user can pass to the controllers.
|
|
56
|
+
#
|
|
57
|
+
# This is useful in the case where certain fields should not be allowed to be modified by the
|
|
58
|
+
# user, or if you add additional fields to the extension's model and you want the users to be able
|
|
59
|
+
# to set them.
|
|
60
|
+
|
|
61
|
+
# Attributes the user can specify for subscriptions.
|
|
62
|
+
# config.subscription_attributes = [
|
|
63
|
+
# :interval_length,
|
|
64
|
+
# :interval_units,
|
|
65
|
+
# :end_date,
|
|
66
|
+
# shipping_address_attributes: Spree::PermittedAttributes.address_attributes,
|
|
67
|
+
# billing_address_attributes: Spree::PermittedAttributes.address_attributes,
|
|
68
|
+
# ]
|
|
69
|
+
|
|
70
|
+
# Attributes the user be specify for subscription line items.
|
|
71
|
+
# config.subscription_line_item_attributes = [
|
|
72
|
+
# :quantity,
|
|
73
|
+
# :subscribable_id,
|
|
74
|
+
# :interval_length,
|
|
75
|
+
# :interval_units,
|
|
76
|
+
# :end_date,
|
|
77
|
+
# ]
|
|
78
|
+
|
|
79
|
+
# ========================================= Churn Buster =========================================
|
|
80
|
+
#
|
|
81
|
+
# This extension can integrate with Churn Buster for churn mitigation and failed payment recovery.
|
|
82
|
+
# If you want to integrate with Churn Buster, simply configure your credentials below.
|
|
83
|
+
#
|
|
84
|
+
# NOTE: If you integrate with Churn Buster and override any of the handlers, make sure to call
|
|
85
|
+
# `super` or copy-paste the original integration code or things won't work!
|
|
86
|
+
|
|
87
|
+
# Your Churn Buster account ID.
|
|
88
|
+
# config.churn_buster_account_id = 'YOUR_CHURN_BUSTER_ACCOUNT_ID'
|
|
89
|
+
|
|
90
|
+
# Your Churn Buster API key.
|
|
91
|
+
# config.churn_buster_api_key = 'YOUR_CHURN_BUSTER_API_KEY'
|
|
92
|
+
|
|
93
|
+
# =================================== Clear past installments ====================================
|
|
94
|
+
#
|
|
95
|
+
# This setting prevents the overlap of old failed installments (e.g. for an expired credit card)
|
|
96
|
+
# with new subscription cycles by clearing any past failed installment when a new one is created
|
|
97
|
+
|
|
98
|
+
# config.clear_past_installments = true
|
|
99
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'solidus_core'
|
|
4
|
+
require 'solidus_support'
|
|
5
|
+
|
|
6
|
+
require 'deface'
|
|
7
|
+
require 'httparty'
|
|
8
|
+
require 'state_machines'
|
|
9
|
+
|
|
10
|
+
require 'solidus_subscriptions/configuration'
|
|
11
|
+
require 'solidus_subscriptions/permission_sets/default_customer'
|
|
12
|
+
require 'solidus_subscriptions/permission_sets/subscription_management'
|
|
13
|
+
require 'solidus_subscriptions/version'
|
|
14
|
+
require 'solidus_subscriptions/engine'
|
|
15
|
+
require 'solidus_subscriptions/churn_buster/client'
|
|
16
|
+
require 'solidus_subscriptions/churn_buster/serializer'
|
|
17
|
+
require 'solidus_subscriptions/churn_buster/subscription_customer_serializer'
|
|
18
|
+
require 'solidus_subscriptions/churn_buster/subscription_payment_method_serializer'
|
|
19
|
+
require 'solidus_subscriptions/churn_buster/subscription_serializer'
|
|
20
|
+
require 'solidus_subscriptions/churn_buster/order_serializer'
|
|
21
|
+
require 'solidus_subscriptions/checkout'
|
|
22
|
+
require 'solidus_subscriptions/subscription_generator'
|
|
23
|
+
require 'solidus_subscriptions/subscription_line_item_builder'
|
|
24
|
+
require 'solidus_subscriptions/dispatcher/base'
|
|
25
|
+
require 'solidus_subscriptions/dispatcher/failure_dispatcher'
|
|
26
|
+
require 'solidus_subscriptions/dispatcher/out_of_stock_dispatcher'
|
|
27
|
+
require 'solidus_subscriptions/dispatcher/payment_failed_dispatcher'
|
|
28
|
+
require 'solidus_subscriptions/dispatcher/success_dispatcher'
|
|
29
|
+
|
|
30
|
+
module SolidusSubscriptions
|
|
31
|
+
class << self
|
|
32
|
+
def configure
|
|
33
|
+
yield configuration
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def configuration
|
|
37
|
+
@configuration ||= Configuration.new
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def churn_buster
|
|
41
|
+
return unless configuration.churn_buster?
|
|
42
|
+
|
|
43
|
+
@churn_buster ||= ChurnBuster::Client.new(
|
|
44
|
+
account_id: SolidusSubscriptions.configuration.churn_buster_account_id,
|
|
45
|
+
api_key: SolidusSubscriptions.configuration.churn_buster_api_key,
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusSubscriptions
|
|
4
|
+
class Checkout
|
|
5
|
+
attr_reader :installment
|
|
6
|
+
|
|
7
|
+
def initialize(installment)
|
|
8
|
+
@installment = installment
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def process
|
|
12
|
+
order = create_order
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
populate_order(order)
|
|
16
|
+
finalize_order(order)
|
|
17
|
+
|
|
18
|
+
SolidusSubscriptions.configuration.success_dispatcher_class.new(installment, order).dispatch
|
|
19
|
+
rescue StateMachines::InvalidTransition
|
|
20
|
+
if order.payments.any?(&:failed?)
|
|
21
|
+
SolidusSubscriptions.configuration.payment_failed_dispatcher_class.new(installment, order).dispatch
|
|
22
|
+
else
|
|
23
|
+
SolidusSubscriptions.configuration.failure_dispatcher_class.new(installment, order).dispatch
|
|
24
|
+
end
|
|
25
|
+
rescue ::Spree::Order::InsufficientStock
|
|
26
|
+
SolidusSubscriptions.configuration.out_of_stock_dispatcher_class.new(installment, order).dispatch
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
order
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def create_order
|
|
35
|
+
::Spree::Order.create(
|
|
36
|
+
user: installment.subscription.user,
|
|
37
|
+
email: installment.subscription.user.email,
|
|
38
|
+
store: installment.subscription.store || ::Spree::Store.default,
|
|
39
|
+
subscription_order: true,
|
|
40
|
+
subscription: installment.subscription,
|
|
41
|
+
currency: installment.subscription.currency
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def populate_order(order)
|
|
46
|
+
installment.subscription.line_items.each do |line_item|
|
|
47
|
+
order.contents.add(line_item.subscribable, line_item.quantity)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def finalize_order(order)
|
|
52
|
+
::Spree::PromotionHandler::Cart.new(order).activate
|
|
53
|
+
order.recalculate
|
|
54
|
+
|
|
55
|
+
order.checkout_steps[0...-1].each do
|
|
56
|
+
case order.state
|
|
57
|
+
when 'address'
|
|
58
|
+
order.ship_address = installment.subscription.shipping_address_to_use
|
|
59
|
+
order.bill_address = installment.subscription.billing_address_to_use
|
|
60
|
+
when 'payment'
|
|
61
|
+
order.payments.create(
|
|
62
|
+
payment_method: installment.subscription.payment_method_to_use,
|
|
63
|
+
source: installment.subscription.payment_source_to_use,
|
|
64
|
+
amount: order.total,
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
order.next!
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
order.complete!
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|