solidus_subscriptions-alpha 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) 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/solidus_subscriptions/version.rb~ +3 -0
  99. data/lib/tasks/process_subscriptions.rake +6 -6
  100. metadata +4 -3
@@ -1,60 +1,60 @@
1
- # This module is responsible for taking SolidusSubscriptions::LineItem
2
- # objects and creating SolidusSubscriptions::Subscription Objects
3
- module SolidusSubscriptions
4
- module SubscriptionGenerator
5
- extend self
6
-
7
- SubscriptionConfiguration = Struct.new(:interval_length, :interval_units, :end_date)
8
-
9
- # Create and persist a subscription for a collection of subscription
10
- # line items
11
- #
12
- # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
13
- # subscription_line_items to be activated
14
- #
15
- # @return [SolidusSubscriptions::Subscription]
16
- def activate(subscription_line_items)
17
- return if subscription_line_items.empty?
18
-
19
- order = subscription_line_items.first.order
20
- configuration = subscription_configuration(subscription_line_items.first)
21
-
22
- subscription_attributes = {
23
- user: order.user,
24
- line_items: subscription_line_items,
25
- store: order.store,
26
- shipping_address: order.ship_address,
27
- **configuration.to_h
28
- }
29
-
30
- Subscription.create!(subscription_attributes) do |sub|
31
- sub.actionable_date = sub.next_actionable_date
32
- end
33
- end
34
-
35
- # Group a collection of line items by common subscription configuration
36
- # options. Grouped subscription_line_items can belong to a single
37
- # subscription.
38
- #
39
- # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
40
- # subscription_line_items to be grouped.
41
- #
42
- # @return [Array<Array<SolidusSubscriptions::LineItem>>]
43
- def group(subscription_line_items)
44
- subscription_line_items.group_by do |li|
45
- subscription_configuration(li)
46
- end.
47
- values
48
- end
49
-
50
- private
51
-
52
- def subscription_configuration(subscription_line_item)
53
- SubscriptionConfiguration.new(
54
- subscription_line_item.interval_length,
55
- subscription_line_item.interval_units,
56
- subscription_line_item.end_date
57
- )
58
- end
59
- end
60
- end
1
+ # This module is responsible for taking SolidusSubscriptions::LineItem
2
+ # objects and creating SolidusSubscriptions::Subscription Objects
3
+ module SolidusSubscriptions
4
+ module SubscriptionGenerator
5
+ extend self
6
+
7
+ SubscriptionConfiguration = Struct.new(:interval_length, :interval_units, :end_date)
8
+
9
+ # Create and persist a subscription for a collection of subscription
10
+ # line items
11
+ #
12
+ # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
13
+ # subscription_line_items to be activated
14
+ #
15
+ # @return [SolidusSubscriptions::Subscription]
16
+ def activate(subscription_line_items)
17
+ return if subscription_line_items.empty?
18
+
19
+ order = subscription_line_items.first.order
20
+ configuration = subscription_configuration(subscription_line_items.first)
21
+
22
+ subscription_attributes = {
23
+ user: order.user,
24
+ line_items: subscription_line_items,
25
+ store: order.store,
26
+ shipping_address: order.ship_address,
27
+ **configuration.to_h
28
+ }
29
+
30
+ Subscription.create!(subscription_attributes) do |sub|
31
+ sub.actionable_date = sub.next_actionable_date
32
+ end
33
+ end
34
+
35
+ # Group a collection of line items by common subscription configuration
36
+ # options. Grouped subscription_line_items can belong to a single
37
+ # subscription.
38
+ #
39
+ # @param subscription_line_items [Array<SolidusSubscriptions::LineItem>] The
40
+ # subscription_line_items to be grouped.
41
+ #
42
+ # @return [Array<Array<SolidusSubscriptions::LineItem>>]
43
+ def group(subscription_line_items)
44
+ subscription_line_items.group_by do |li|
45
+ subscription_configuration(li)
46
+ end.
47
+ values
48
+ end
49
+
50
+ private
51
+
52
+ def subscription_configuration(subscription_line_item)
53
+ SubscriptionConfiguration.new(
54
+ subscription_line_item.interval_length,
55
+ subscription_line_item.interval_units,
56
+ subscription_line_item.end_date
57
+ )
58
+ end
59
+ end
60
+ end
@@ -1,21 +1,21 @@
1
- module SolidusSubscriptions
2
- module SubscriptionLineItemBuilder
3
- private
4
-
5
- def create_subscription_line_item(line_item)
6
- SolidusSubscriptions::LineItem.create!(
7
- subscription_params.merge(spree_line_item: line_item)
8
- )
9
-
10
- # Rerun the promotion handler to pickup subscription promotions
11
- Spree::PromotionHandler::Cart.new(line_item.order).activate
12
- line_item.order.update!
13
- end
14
-
15
- def subscription_params
16
- params.require(:subscription_line_item).permit(
17
- SolidusSubscriptions::Config.subscription_line_item_attributes
18
- )
19
- end
20
- end
21
- end
1
+ module SolidusSubscriptions
2
+ module SubscriptionLineItemBuilder
3
+ private
4
+
5
+ def create_subscription_line_item(line_item)
6
+ SolidusSubscriptions::LineItem.create!(
7
+ subscription_params.merge(spree_line_item: line_item)
8
+ )
9
+
10
+ # Rerun the promotion handler to pickup subscription promotions
11
+ Spree::PromotionHandler::Cart.new(line_item.order).activate
12
+ line_item.order.update!
13
+ end
14
+
15
+ def subscription_params
16
+ params.require(:subscription_line_item).permit(
17
+ SolidusSubscriptions::Config.subscription_line_item_attributes
18
+ )
19
+ end
20
+ end
21
+ end
@@ -1,25 +1,25 @@
1
- module SolidusSubscriptions
2
- class SubscriptionOrderPromotionRule < Spree::PromotionRule
3
- # Promotion can be applied to an entire order. Will only be true
4
- # for Spree::Order
5
- #
6
- # @param promotable [Object] Any object which could have this
7
- # promotion rule applied to it.
8
- #
9
- # @return [Boolean]
10
- def applicable?(promotable)
11
- promotable.is_a? Spree::Order
12
- end
13
-
14
- # An order is eligible if it fulfills a subscription Installment. Will only
15
- # return true if the order fulfills one or more Installments
16
- #
17
- # @param order [Spree::Order] The order which could have this rule applied
18
- # to it.
19
- #
20
- # @return [Boolean]
21
- def eligible?(order, **_options)
22
- order.subscription_order?
23
- end
24
- end
25
- end
1
+ module SolidusSubscriptions
2
+ class SubscriptionOrderPromotionRule < Spree::PromotionRule
3
+ # Promotion can be applied to an entire order. Will only be true
4
+ # for Spree::Order
5
+ #
6
+ # @param promotable [Object] Any object which could have this
7
+ # promotion rule applied to it.
8
+ #
9
+ # @return [Boolean]
10
+ def applicable?(promotable)
11
+ promotable.is_a? Spree::Order
12
+ end
13
+
14
+ # An order is eligible if it fulfills a subscription Installment. Will only
15
+ # return true if the order fulfills one or more Installments
16
+ #
17
+ # @param order [Spree::Order] The order which could have this rule applied
18
+ # to it.
19
+ #
20
+ # @return [Boolean]
21
+ def eligible?(order, **_options)
22
+ order.subscription_order?
23
+ end
24
+ end
25
+ end
@@ -1,38 +1,38 @@
1
- module SolidusSubscriptions
2
- class SubscriptionPromotionRule < Spree::PromotionRule
3
- # Promotion can be applied to an entire order. Will only be true
4
- # for Spree::Order
5
- #
6
- # @param promotable [Object] Any object which could have this
7
- # promotion rule applied to it.
8
- #
9
- # @return [Boolean]
10
- def applicable?(promotable)
11
- promotable.is_a? Spree::Order
12
- end
13
-
14
- # An order is eligible if it contains a line item with an associates
15
- # subscription_line_item. This rule applies to order and so its eligibility
16
- # will always be considered against an order. Will only return true for
17
- # orders containing Spree::Line item with associated subscription_line_items
18
- #
19
- # @param order [Spree::Order] The order which could have this rule applied
20
- # to it.
21
- #
22
- # @return [Boolean]
23
- def eligible?(order, **_options)
24
- order.subscription_line_items.any?
25
- end
26
-
27
- # Certain actions create adjustments on line items. In this case, only
28
- # line items with associated subscription_line_itms are eligible to be
29
- # adjusted. Will only return true # if :line_item has an associated
30
- # subscription.
31
- #
32
- # @param line_item [Spree::LineItem] The line item which could be adjusted
33
- # by the promotion.
34
- def actionable?(line_item)
35
- line_item.subscription_line_items.present?
36
- end
37
- end
38
- end
1
+ module SolidusSubscriptions
2
+ class SubscriptionPromotionRule < Spree::PromotionRule
3
+ # Promotion can be applied to an entire order. Will only be true
4
+ # for Spree::Order
5
+ #
6
+ # @param promotable [Object] Any object which could have this
7
+ # promotion rule applied to it.
8
+ #
9
+ # @return [Boolean]
10
+ def applicable?(promotable)
11
+ promotable.is_a? Spree::Order
12
+ end
13
+
14
+ # An order is eligible if it contains a line item with an associates
15
+ # subscription_line_item. This rule applies to order and so its eligibility
16
+ # will always be considered against an order. Will only return true for
17
+ # orders containing Spree::Line item with associated subscription_line_items
18
+ #
19
+ # @param order [Spree::Order] The order which could have this rule applied
20
+ # to it.
21
+ #
22
+ # @return [Boolean]
23
+ def eligible?(order, **_options)
24
+ order.subscription_line_items.any?
25
+ end
26
+
27
+ # Certain actions create adjustments on line items. In this case, only
28
+ # line items with associated subscription_line_itms are eligible to be
29
+ # adjusted. Will only return true # if :line_item has an associated
30
+ # subscription.
31
+ #
32
+ # @param line_item [Spree::LineItem] The line item which could be adjusted
33
+ # by the promotion.
34
+ def actionable?(line_item)
35
+ line_item.subscription_line_items.present?
36
+ end
37
+ end
38
+ end
@@ -1,16 +1,16 @@
1
- # This service class is intented to provide callback behaviour to handle
2
- # an installment successfully being processed
3
- module SolidusSubscriptions
4
- class SuccessDispatcher < Dispatcher
5
- def dispatch
6
- installments.each { |i| i.success!(order) }
7
- super
8
- end
9
-
10
- private
11
-
12
- def message
13
- "Successfully processed installments: #{installments.map(&:id).join(', ')}"
14
- end
15
- end
16
- end
1
+ # This service class is intented to provide callback behaviour to handle
2
+ # an installment successfully being processed
3
+ module SolidusSubscriptions
4
+ class SuccessDispatcher < Dispatcher
5
+ def dispatch
6
+ installments.each { |i| i.success!(order) }
7
+ super
8
+ end
9
+
10
+ private
11
+
12
+ def message
13
+ "Successfully processed installments: #{installments.map(&:id).join(', ')}"
14
+ end
15
+ end
16
+ end
@@ -1,17 +1,17 @@
1
- # This error should be raised if a user attempts to subscribe to a item which
2
- # is not subscribable
3
- module SolidusSubscriptions
4
- class UnsubscribableError < StandardError
5
- def initialize(subscribable)
6
- @subscribable = subscribable
7
- super
8
- end
9
-
10
- def to_s
11
- <<-MSG.squish
12
- #{@subscribable.class} with id: #{@subscribable.id} cannot be
13
- subscribed to.
14
- MSG
15
- end
16
- end
17
- end
1
+ # This error should be raised if a user attempts to subscribe to a item which
2
+ # is not subscribable
3
+ module SolidusSubscriptions
4
+ class UnsubscribableError < StandardError
5
+ def initialize(subscribable)
6
+ @subscribable = subscribable
7
+ super
8
+ end
9
+
10
+ def to_s
11
+ <<-MSG.squish
12
+ #{@subscribable.class} with id: #{@subscribable.id} cannot be
13
+ subscribed to.
14
+ MSG
15
+ end
16
+ end
17
+ end
@@ -1,15 +1,15 @@
1
- module SolidusSubscriptions
2
- class UserMismatchError < StandardError
3
- def initialize(installments)
4
- @installments = installments
5
- end
6
-
7
- def to_s
8
- <<-MSG.squish
9
- Installments must have the same user to be processed as a consolidated
10
- installment. Could not process installments:
11
- #{@installments.map(&:id).join(', ')}
12
- MSG
13
- end
14
- end
15
- end
1
+ module SolidusSubscriptions
2
+ class UserMismatchError < StandardError
3
+ def initialize(installments)
4
+ @installments = installments
5
+ end
6
+
7
+ def to_s
8
+ <<-MSG.squish
9
+ Installments must have the same user to be processed as a consolidated
10
+ installment. Could not process installments:
11
+ #{@installments.map(&:id).join(', ')}
12
+ MSG
13
+ end
14
+ end
15
+ end
@@ -1,13 +1,13 @@
1
- Deface::Override.new(
2
- virtual_path: "spree/admin/variants/_form",
3
- name: "solidus_subscriptions_subscribable_checkbox",
4
- insert_after: "[data-hook='track_inventory']",
5
- partial: "spree/admin/variants/subscribable_checkbox"
6
- )
7
-
8
- Deface::Override.new(
9
- virtual_path: "spree/admin/products/_form",
10
- name: "solidus_subscriptions_product_subscribable_checkbox",
11
- insert_after: "[data-hook='admin_product_form_meta']",
12
- partial: "spree/admin/products/subscribable_checkbox"
13
- )
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/variants/_form",
3
+ name: "solidus_subscriptions_subscribable_checkbox",
4
+ insert_after: "[data-hook='track_inventory']",
5
+ partial: "spree/admin/variants/subscribable_checkbox"
6
+ )
7
+
8
+ Deface::Override.new(
9
+ virtual_path: "spree/admin/products/_form",
10
+ name: "solidus_subscriptions_product_subscribable_checkbox",
11
+ insert_after: "[data-hook='admin_product_form_meta']",
12
+ partial: "spree/admin/products/subscribable_checkbox"
13
+ )
@@ -1,8 +1,8 @@
1
- if !Spree::Backend::Config.respond_to?(:menu_items)
2
- Deface::Override.new(
3
- virtual_path: 'spree/admin/shared/_menu',
4
- name: :add_subcriptions_admin_link,
5
- insert_bottom: "[data-hook='admin_tabs']",
6
- partial: 'spree/admin/shared/subscription_tab'
7
- )
8
- end
1
+ if !Spree::Backend::Config.respond_to?(:menu_items)
2
+ Deface::Override.new(
3
+ virtual_path: 'spree/admin/shared/_menu',
4
+ name: :add_subcriptions_admin_link,
5
+ insert_bottom: "[data-hook='admin_tabs']",
6
+ partial: 'spree/admin/shared/subscription_tab'
7
+ )
8
+ end
@@ -1,6 +1,6 @@
1
- Deface::Override.new(
2
- virtual_path: "spree/products/_cart_form",
3
- name: "subscription_line_item_fields",
4
- insert_after: "[data-hook='inside_product_cart_form']",
5
- partial: "spree/frontend/products/subscription_line_item_fields"
6
- )
1
+ Deface::Override.new(
2
+ virtual_path: "spree/products/_cart_form",
3
+ name: "subscription_line_item_fields",
4
+ insert_after: "[data-hook='inside_product_cart_form']",
5
+ partial: "spree/frontend/products/subscription_line_item_fields"
6
+ )