solidus_subscriptions-alpha 0.0.3 → 0.0.4

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +26 -26
  3. data/README.md +130 -130
  4. data/Rakefile +28 -28
  5. data/app/assets/javascripts/spree/backend/solidus_subscriptions.js +1 -1
  6. data/app/assets/javascripts/spree/frontend/solidus_subscriptions.js +1 -1
  7. data/app/assets/stylesheets/spree/backend/solidus_subscriptions.css +4 -4
  8. data/app/assets/stylesheets/spree/frontend/solidus_subscriptions.css +4 -4
  9. data/app/controllers/solidus_subscriptions/api/v1/line_items_controller.rb +35 -35
  10. data/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb +44 -44
  11. data/app/controllers/spree/admin/subscriptions_controller.rb +66 -66
  12. data/app/decorators/spree/controllers/api/line_items/create_subscription_line_items.rb +28 -28
  13. data/app/decorators/spree/controllers/orders/create_subscription_line_items.rb +33 -33
  14. data/app/decorators/spree/line_items/subscription_line_items_association.rb +22 -22
  15. data/app/decorators/spree/orders/after_create.rb +15 -15
  16. data/app/decorators/spree/orders/finalize_creates_subscriptions.rb +19 -19
  17. data/app/decorators/spree/orders/subscription_line_items_association.rb +15 -15
  18. data/app/decorators/spree/products/subscribable_decorator.rb +11 -11
  19. data/app/decorators/spree/users/have_many_subscriptions.rb +18 -18
  20. data/app/decorators/spree/variant_pretty_name.rb +13 -13
  21. data/app/jobs/solidus_subscriptions/process_installments_job.rb +22 -22
  22. data/app/models/solidus_subscriptions/checkout.rb +141 -141
  23. data/app/models/solidus_subscriptions/dispatcher.rb +32 -32
  24. data/app/models/solidus_subscriptions/failure_dispatcher.rb +19 -19
  25. data/app/models/solidus_subscriptions/installment.rb +126 -126
  26. data/app/models/solidus_subscriptions/installment_detail.rb +23 -23
  27. data/app/models/solidus_subscriptions/interval.rb +24 -24
  28. data/app/models/solidus_subscriptions/line_item.rb +98 -98
  29. data/app/models/solidus_subscriptions/line_item_builder.rb +44 -44
  30. data/app/models/solidus_subscriptions/order_builder.rb +40 -40
  31. data/app/models/solidus_subscriptions/out_of_stock_dispatcher.rb +19 -19
  32. data/app/models/solidus_subscriptions/payment_failed_dispatcher.rb +23 -23
  33. data/app/models/solidus_subscriptions/subscription.rb +217 -217
  34. data/app/models/solidus_subscriptions/subscription_generator.rb +60 -60
  35. data/app/models/solidus_subscriptions/subscription_line_item_builder.rb +21 -21
  36. data/app/models/solidus_subscriptions/subscription_order_promotion_rule.rb +25 -25
  37. data/app/models/solidus_subscriptions/subscription_promotion_rule.rb +38 -38
  38. data/app/models/solidus_subscriptions/success_dispatcher.rb +16 -16
  39. data/app/models/solidus_subscriptions/unsubscribable_error.rb +17 -17
  40. data/app/models/solidus_subscriptions/user_mismatch_error.rb +15 -15
  41. data/app/overrides/views/admin_subscribable_checkbox.rb +13 -13
  42. data/app/overrides/views/admin_subscriptions_menu_link.rb +8 -8
  43. data/app/overrides/views/subscription_line_item_fields.rb +6 -6
  44. data/app/views/spree/admin/products/_subscribable_checkbox.html.erb +8 -8
  45. data/app/views/spree/admin/promotions/rules/_subscription_order_promotion_rule.html.erb +0 -0
  46. data/app/views/spree/admin/promotions/rules/_subscription_promotion_rule.html.erb +0 -0
  47. data/app/views/spree/admin/shared/_no_objects_found.html.erb +4 -4
  48. data/app/views/spree/admin/shared/_subscription_tab.html.erb +3 -3
  49. data/app/views/spree/admin/solidus_subscriptions/subscriptions/_subscription.html.erb +66 -66
  50. data/app/views/spree/admin/subscriptions/_form.html.erb +81 -81
  51. data/app/views/spree/admin/subscriptions/_legacy_form.html.erb +81 -81
  52. data/app/views/spree/admin/subscriptions/_legacy_sidebar.html.erb +28 -28
  53. data/app/views/spree/admin/subscriptions/edit.html.erb +21 -21
  54. data/app/views/spree/admin/subscriptions/index.html.erb +119 -119
  55. data/app/views/spree/admin/subscriptions/new.html.erb +9 -9
  56. data/app/views/spree/admin/variants/_subscribable_checkbox.html.erb +6 -6
  57. data/app/views/spree/frontend/products/_subscription_line_item_fields.html.erb +30 -30
  58. data/config/locales/en.yml +91 -91
  59. data/config/routes.rb +25 -25
  60. data/db/migrate/20160825164850_create_solidus_subscriptions_subscriptions.rb +11 -11
  61. data/db/migrate/20160825173548_create_solidus_subscriptions_line_items.rb +17 -17
  62. data/db/migrate/20160825202248_create_solidus_subscriptions_installments.rb +23 -23
  63. data/db/migrate/20160825211202_create_solidus_subscriptions_installment_details.rb +22 -22
  64. data/db/migrate/20160825214240_add_subscribable_to_spree_variants.rb +5 -5
  65. data/db/migrate/20160829201653_change_subscription_line_items_installments_to_max_installments.rb +5 -5
  66. data/db/migrate/20160902220242_remove_state_from_solidus_susbscriptions_installment_details.rb +5 -5
  67. data/db/migrate/20160902220604_add_successful_to_solidus_subscriptions_installment_details.rb +5 -5
  68. data/db/migrate/20160902221218_add_message_to_solidus_subscriptions_installment_details.rb +5 -5
  69. data/db/migrate/20160922164101_add_interval_length_and_units_to_subscription_line_items.rb +8 -8
  70. data/db/migrate/20161006191003_add_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -5
  71. data/db/migrate/20161006191127_add_successive_skip_count_to_solidus_subscriptions_subscriptions.rb +5 -5
  72. data/db/migrate/20161014212649_allow_spree_line_item_id_to_be_null.rb +5 -5
  73. data/db/migrate/20161017155749_add_order_id_to_solidus_subscriptions_installment_details.rb +6 -6
  74. data/db/migrate/20161017175509_remove_order_id_from_solidus_subscriptions_installments.rb +6 -6
  75. data/db/migrate/20161017201944_add_subscription_order_to_spree_orders.rb +5 -5
  76. data/db/migrate/20161221155142_add_store_to_solidus_subscriptions_subscriptions.rb +6 -6
  77. data/db/migrate/20161223152905_add_address_id_to_solidus_subscriptions_subscriptions.rb +7 -7
  78. data/db/migrate/20170106224713_change_line_item_max_installments_to_end_date.rb +6 -6
  79. data/db/migrate/20170111224458_change_subscription_actionable_date_to_datetime.rb +5 -5
  80. data/db/migrate/20170111232801_change_inteval_actionable_date_to_datetime.rb +5 -5
  81. data/db/migrate/20170112012407_add_config_options_to_subscriptions.rb +7 -7
  82. data/lib/generators/solidus_subscriptions/install/install_generator.rb +30 -30
  83. data/lib/solidus_subscriptions.rb +6 -6
  84. data/lib/solidus_subscriptions/ability.rb +19 -19
  85. data/lib/solidus_subscriptions/config.rb +97 -97
  86. data/lib/solidus_subscriptions/engine.rb +56 -56
  87. data/lib/solidus_subscriptions/permitted_attributes.rb +36 -36
  88. data/lib/solidus_subscriptions/processor.rb +108 -108
  89. data/lib/solidus_subscriptions/testing_support/factories.rb +5 -5
  90. data/lib/solidus_subscriptions/testing_support/factories/installment_detail_factory.rb +7 -7
  91. data/lib/solidus_subscriptions/testing_support/factories/installment_factory.rb +21 -21
  92. data/lib/solidus_subscriptions/testing_support/factories/line_item_factory.rb +18 -18
  93. data/lib/solidus_subscriptions/testing_support/factories/spree/line_item_factory.rb +17 -17
  94. data/lib/solidus_subscriptions/testing_support/factories/spree/order_factory.rb +18 -18
  95. data/lib/solidus_subscriptions/testing_support/factories/spree_modification_factory.rb +8 -8
  96. data/lib/solidus_subscriptions/testing_support/factories/subscription_factory.rb +43 -43
  97. data/lib/solidus_subscriptions/version.rb +3 -3
  98. data/lib/tasks/process_subscriptions.rake +6 -6
  99. metadata +3 -3
@@ -1,56 +1,56 @@
1
- module SolidusSubscriptions
2
- class Engine < Rails::Engine
3
- require 'spree/core'
4
- require 'solidus_subscriptions/permitted_attributes'
5
- require 'solidus_subscriptions/config'
6
- require 'solidus_subscriptions/processor'
7
-
8
- isolate_namespace SolidusSubscriptions
9
- engine_name 'solidus_subscriptions'
10
-
11
- # use rspec for tests
12
- config.generators do |g|
13
- g.test_framework :rspec
14
- end
15
-
16
- config.autoload_paths << config.root.join('app', 'jobs')
17
-
18
- initializer 'configure spree subcription permitted attributes', after: 'require subscription lib helpers' do
19
- PermittedAttributes.update_spree_permiteed_attributes
20
- end
21
-
22
- initializer 'solidus_subscriptions.configs', before: "require subscription lib helpers" do
23
- end
24
-
25
- initializer 'register_subscription_promotion_rule', after: 'spree.promo.register.promotion.rules' do |app|
26
- app.config.spree.promotions.rules << 'SolidusSubscriptions::SubscriptionPromotionRule'
27
- app.config.spree.promotions.rules << 'SolidusSubscriptions::SubscriptionOrderPromotionRule'
28
- end
29
-
30
- initializer 'subscriptions_backend' do
31
- next unless Spree::Backend::Config.respond_to?(:menu_items)
32
- Spree::Backend::Config.configure do |config|
33
- config.menu_items << config.class::MenuItem.new(
34
- [:subscriptions],
35
- 'repeat',
36
- url: :admin_subscriptions_path,
37
- condition: ->{ can?(:admin, SolidusSubscriptions::Subscription) }
38
- )
39
- end
40
- end
41
-
42
- def self.activate
43
- Dir.glob(File.join(File.dirname(__FILE__), '../../app/decorators/**/*.rb')) do |c|
44
- Rails.configuration.cache_classes ? require(c) : load(c)
45
- end
46
-
47
- Spree::Ability.register_ability(SolidusSubscriptions::Ability)
48
- end
49
-
50
- config.to_prepare(&method(:activate).to_proc)
51
- end
52
-
53
- def self.table_name_prefix
54
- 'solidus_subscriptions_'
55
- end
56
- end
1
+ module SolidusSubscriptions
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ require 'solidus_subscriptions/permitted_attributes'
5
+ require 'solidus_subscriptions/config'
6
+ require 'solidus_subscriptions/processor'
7
+
8
+ isolate_namespace SolidusSubscriptions
9
+ engine_name 'solidus_subscriptions'
10
+
11
+ # use rspec for tests
12
+ config.generators do |g|
13
+ g.test_framework :rspec
14
+ end
15
+
16
+ config.autoload_paths << config.root.join('app', 'jobs')
17
+
18
+ initializer 'configure spree subcription permitted attributes', after: 'require subscription lib helpers' do
19
+ PermittedAttributes.update_spree_permiteed_attributes
20
+ end
21
+
22
+ initializer 'solidus_subscriptions.configs', before: "require subscription lib helpers" do
23
+ end
24
+
25
+ initializer 'register_subscription_promotion_rule', after: 'spree.promo.register.promotion.rules' do |app|
26
+ app.config.spree.promotions.rules << 'SolidusSubscriptions::SubscriptionPromotionRule'
27
+ app.config.spree.promotions.rules << 'SolidusSubscriptions::SubscriptionOrderPromotionRule'
28
+ end
29
+
30
+ initializer 'subscriptions_backend' do
31
+ next unless Spree::Backend::Config.respond_to?(:menu_items)
32
+ Spree::Backend::Config.configure do |config|
33
+ config.menu_items << config.class::MenuItem.new(
34
+ [:subscriptions],
35
+ 'repeat',
36
+ url: :admin_subscriptions_path,
37
+ condition: ->{ can?(:admin, SolidusSubscriptions::Subscription) }
38
+ )
39
+ end
40
+ end
41
+
42
+ def self.activate
43
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/decorators/**/*.rb')) do |c|
44
+ Rails.configuration.cache_classes ? require(c) : load(c)
45
+ end
46
+
47
+ Spree::Ability.register_ability(SolidusSubscriptions::Ability)
48
+ end
49
+
50
+ config.to_prepare(&method(:activate).to_proc)
51
+ end
52
+
53
+ def self.table_name_prefix
54
+ 'solidus_subscriptions_'
55
+ end
56
+ end
@@ -1,36 +1,36 @@
1
- # This module is responsible for managing what attributes can be updated
2
- # through the api. It also overrides Spree::Permitted attributes to allow the
3
- # solidus api to accept nested params for subscription models as well
4
- module SolidusSubscriptions
5
- module PermittedAttributes
6
- class << self
7
- def update_spree_permiteed_attributes
8
- Spree::PermittedAttributes.line_item_attributes << {
9
- subscription_line_items_attributes: nested(
10
- subscription_line_item_attributes
11
- )
12
- }
13
-
14
- Spree::PermittedAttributes.user_attributes << {
15
- subscriptions_attributes: nested(subscription_attributes)
16
- }
17
- end
18
-
19
- def subscription_line_item_attributes
20
- [Config.subscription_line_item_attributes]
21
- end
22
-
23
- def subscription_attributes
24
- Config.subscription_attributes | [
25
- { line_items_attributes: nested(subscription_line_item_attributes) - [:subscribable_id] }
26
- ]
27
- end
28
-
29
- private
30
-
31
- def nested(attributes)
32
- attributes | [:id]
33
- end
34
- end
35
- end
36
- end
1
+ # This module is responsible for managing what attributes can be updated
2
+ # through the api. It also overrides Spree::Permitted attributes to allow the
3
+ # solidus api to accept nested params for subscription models as well
4
+ module SolidusSubscriptions
5
+ module PermittedAttributes
6
+ class << self
7
+ def update_spree_permiteed_attributes
8
+ Spree::PermittedAttributes.line_item_attributes << {
9
+ subscription_line_items_attributes: nested(
10
+ subscription_line_item_attributes
11
+ )
12
+ }
13
+
14
+ Spree::PermittedAttributes.user_attributes << {
15
+ subscriptions_attributes: nested(subscription_attributes)
16
+ }
17
+ end
18
+
19
+ def subscription_line_item_attributes
20
+ [Config.subscription_line_item_attributes]
21
+ end
22
+
23
+ def subscription_attributes
24
+ Config.subscription_attributes | [
25
+ { line_items_attributes: nested(subscription_line_item_attributes) - [:subscribable_id] }
26
+ ]
27
+ end
28
+
29
+ private
30
+
31
+ def nested(attributes)
32
+ attributes | [:id]
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,108 +1,108 @@
1
- # This class is responsible for finding subscriptions and installments
2
- # which need to be processed. It will group them together by user and attempts
3
- # to process them together. Subscriptions will also be grouped by their
4
- # shiping address id.
5
- #
6
- # This class passes the reponsibility of actually creating the order off onto
7
- # the consolidated installment class.
8
- #
9
- # This class generates `ProcessInstallmentsJob`s
10
- module SolidusSubscriptions
11
- class Processor
12
- class << self
13
- # Find all actionable subscriptions and intallments, group them together
14
- # by user, and schedule a processing job for the group as a batch
15
- def run
16
- batched_users_to_be_processed.each { |batch| new(batch).build_jobs }
17
- end
18
-
19
- private
20
-
21
- def batched_users_to_be_processed
22
- subscriptions = SolidusSubscriptions::Subscription.arel_table
23
- installments = SolidusSubscriptions::Installment.arel_table
24
-
25
- Spree::User.
26
- joins(:subscriptions).
27
- joins(
28
- subscriptions.
29
- join(installments, Arel::Nodes::OuterJoin).
30
- on(subscriptions[:id].eq(installments[:subscription_id])).
31
- join_sources
32
- ).
33
- where(
34
- SolidusSubscriptions::Subscription.actionable.arel.constraints.reduce(:and).
35
- or(SolidusSubscriptions::Installment.actionable.arel.constraints.reduce(:and))
36
- ).
37
- distinct.
38
- find_in_batches
39
- end
40
- end
41
-
42
- # @return [Array<Spree.user_class>]
43
- attr_reader :users
44
-
45
- # Get a new instance of the SolidusSubscriptions::Processor
46
- #
47
- # @param users [Array<Spree.user_class>] A list of users with actionable
48
- # subscriptions or installments
49
- #
50
- # @return [SolidusSubscriptions::Processor]
51
- def initialize(users)
52
- @users = users
53
- @installments = {}
54
- end
55
-
56
- # Create `ProcessInstallmentsJob`s for the users used to initalize the
57
- # instance
58
- def build_jobs
59
- users.map do |user|
60
- installemts_by_address_and_user = installments(user).group_by do |i|
61
- i.subscription.shipping_address_id
62
- end
63
-
64
- installemts_by_address_and_user.values.each do |grouped_installments|
65
- ProcessInstallmentsJob.perform_later grouped_installments.map(&:id)
66
- end
67
- end
68
- end
69
-
70
- private
71
-
72
- def subscriptions_by_id
73
- @subscriptions_by_id ||= Subscription.
74
- actionable.
75
- includes(:line_items, :user).
76
- where(user_id: user_ids).
77
- group_by(&:user_id)
78
- end
79
-
80
- def retry_installments
81
- @failed_installments ||= Installment.
82
- actionable.
83
- includes(:subscription).
84
- where(solidus_subscriptions_subscriptions: { user_id: user_ids }).
85
- group_by { |i| i.subscription.user_id }
86
- end
87
-
88
- def installments(user)
89
- @installments[user.id] ||= retry_installments.fetch(user.id, []) + new_installments(user)
90
- end
91
-
92
- def new_installments(user)
93
- ActiveRecord::Base.transaction do
94
- subscriptions_by_id.fetch(user.id, []).map do |sub|
95
- sub.successive_skip_count = 0
96
- sub.advance_actionable_date
97
- sub.cancel! if sub.pending_cancellation?
98
- sub.deactivate! if sub.can_be_deactivated?
99
- sub.installments.create!
100
- end
101
- end
102
- end
103
-
104
- def user_ids
105
- @user_ids ||= users.map(&:id)
106
- end
107
- end
108
- end
1
+ # This class is responsible for finding subscriptions and installments
2
+ # which need to be processed. It will group them together by user and attempts
3
+ # to process them together. Subscriptions will also be grouped by their
4
+ # shiping address id.
5
+ #
6
+ # This class passes the reponsibility of actually creating the order off onto
7
+ # the consolidated installment class.
8
+ #
9
+ # This class generates `ProcessInstallmentsJob`s
10
+ module SolidusSubscriptions
11
+ class Processor
12
+ class << self
13
+ # Find all actionable subscriptions and intallments, group them together
14
+ # by user, and schedule a processing job for the group as a batch
15
+ def run
16
+ batched_users_to_be_processed.each { |batch| new(batch).build_jobs }
17
+ end
18
+
19
+ private
20
+
21
+ def batched_users_to_be_processed
22
+ subscriptions = SolidusSubscriptions::Subscription.arel_table
23
+ installments = SolidusSubscriptions::Installment.arel_table
24
+
25
+ Spree::User.
26
+ joins(:subscriptions).
27
+ joins(
28
+ subscriptions.
29
+ join(installments, Arel::Nodes::OuterJoin).
30
+ on(subscriptions[:id].eq(installments[:subscription_id])).
31
+ join_sources
32
+ ).
33
+ where(
34
+ SolidusSubscriptions::Subscription.actionable.arel.constraints.reduce(:and).
35
+ or(SolidusSubscriptions::Installment.actionable.arel.constraints.reduce(:and))
36
+ ).
37
+ distinct.
38
+ find_in_batches
39
+ end
40
+ end
41
+
42
+ # @return [Array<Spree.user_class>]
43
+ attr_reader :users
44
+
45
+ # Get a new instance of the SolidusSubscriptions::Processor
46
+ #
47
+ # @param users [Array<Spree.user_class>] A list of users with actionable
48
+ # subscriptions or installments
49
+ #
50
+ # @return [SolidusSubscriptions::Processor]
51
+ def initialize(users)
52
+ @users = users
53
+ @installments = {}
54
+ end
55
+
56
+ # Create `ProcessInstallmentsJob`s for the users used to initalize the
57
+ # instance
58
+ def build_jobs
59
+ users.map do |user|
60
+ installemts_by_address_and_user = installments(user).group_by do |i|
61
+ i.subscription.shipping_address_id
62
+ end
63
+
64
+ installemts_by_address_and_user.values.each do |grouped_installments|
65
+ ProcessInstallmentsJob.perform_later grouped_installments.map(&:id)
66
+ end
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def subscriptions_by_id
73
+ @subscriptions_by_id ||= Subscription.
74
+ actionable.
75
+ includes(:line_items, :user).
76
+ where(user_id: user_ids).
77
+ group_by(&:user_id)
78
+ end
79
+
80
+ def retry_installments
81
+ @failed_installments ||= Installment.
82
+ actionable.
83
+ includes(:subscription).
84
+ where(solidus_subscriptions_subscriptions: { user_id: user_ids }).
85
+ group_by { |i| i.subscription.user_id }
86
+ end
87
+
88
+ def installments(user)
89
+ @installments[user.id] ||= retry_installments.fetch(user.id, []) + new_installments(user)
90
+ end
91
+
92
+ def new_installments(user)
93
+ ActiveRecord::Base.transaction do
94
+ subscriptions_by_id.fetch(user.id, []).map do |sub|
95
+ sub.successive_skip_count = 0
96
+ sub.advance_actionable_date
97
+ sub.cancel! if sub.pending_cancellation?
98
+ sub.deactivate! if sub.can_be_deactivated?
99
+ sub.installments.create!
100
+ end
101
+ end
102
+ end
103
+
104
+ def user_ids
105
+ @user_ids ||= users.map(&:id)
106
+ end
107
+ end
108
+ end
@@ -1,5 +1,5 @@
1
- require 'factory_girl'
2
- require 'spree/testing_support/factories'
3
-
4
- factory_path = "#{File.dirname(__FILE__)}/factories/**/*_factory.rb"
5
- Dir[factory_path].each { |f| require File.expand_path(f) }
1
+ require 'factory_girl'
2
+ require 'spree/testing_support/factories'
3
+
4
+ factory_path = "#{File.dirname(__FILE__)}/factories/**/*_factory.rb"
5
+ Dir[factory_path].each { |f| require File.expand_path(f) }
@@ -1,7 +1,7 @@
1
- FactoryGirl.define do
2
- factory :installment_detail, class: 'SolidusSubscriptions::InstallmentDetail' do
3
- installment
4
-
5
- trait(:success) { success true }
6
- end
7
- end
1
+ FactoryGirl.define do
2
+ factory :installment_detail, class: 'SolidusSubscriptions::InstallmentDetail' do
3
+ installment
4
+
5
+ trait(:success) { success true }
6
+ end
7
+ end
@@ -1,21 +1,21 @@
1
- FactoryGirl.define do
2
- factory :installment, class: 'SolidusSubscriptions::Installment' do
3
- transient { subscription_traits [] }
4
- subscription { build :subscription, :with_line_item, *subscription_traits }
5
-
6
- trait :failed do
7
- actionable_date { Time.zone.yesterday }
8
- details { build_list(:installment_detail, 1, installment: @instance) }
9
- end
10
-
11
- trait :success do
12
- transient do
13
- order { create :completed_order_with_totals }
14
- end
15
-
16
- details do
17
- build_list(:installment_detail, 1, :success, installment: @instance, order: order)
18
- end
19
- end
20
- end
21
- end
1
+ FactoryGirl.define do
2
+ factory :installment, class: 'SolidusSubscriptions::Installment' do
3
+ transient { subscription_traits [] }
4
+ subscription { build :subscription, :with_line_item, *subscription_traits }
5
+
6
+ trait :failed do
7
+ actionable_date { Time.zone.yesterday }
8
+ details { build_list(:installment_detail, 1, installment: @instance) }
9
+ end
10
+
11
+ trait :success do
12
+ transient do
13
+ order { create :completed_order_with_totals }
14
+ end
15
+
16
+ details do
17
+ build_list(:installment_detail, 1, :success, installment: @instance, order: order)
18
+ end
19
+ end
20
+ end
21
+ end